1824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm/* libunwind - a platform-independent unwind library 264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm Copyright (C) 2003-2004 Hewlett-Packard Co 303e05b41386fd5797cb8cd62eff7f0ba77c4e07eDavid Mosberger-Tang Copyright (C) 2007 David Mosberger-Tang 403e05b41386fd5797cb8cd62eff7f0ba77c4e07eDavid Mosberger-Tang Contributed by David Mosberger-Tang <dmosberger@gmail.com> 5824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm 6824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmThis file is part of libunwind. 7824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm 8824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmPermission is hereby granted, free of charge, to any person obtaining 9824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidma copy of this software and associated documentation files (the 10824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm"Software"), to deal in the Software without restriction, including 11824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmwithout limitation the rights to use, copy, modify, merge, publish, 12824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to 13824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmpermit persons to whom the Software is furnished to do so, subject to 14824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmthe following conditions: 15824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm 16824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmThe above copyright notice and this permission notice shall be 17824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmincluded in all copies or substantial portions of the Software. 18824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm 19824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 23824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 24824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 26824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm 27824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm#ifndef os_linux_h 28824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm#define os_linux_h 29824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm 307d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris#include <sys/mman.h> 317d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris 32824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmstruct map_iterator 33824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm { 3464c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm off_t offset; 3564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm int fd; 365de4b351e7624889db611e10dd3034e0176db5eemostang.com!davidm size_t buf_size; 375de4b351e7624889db611e10dd3034e0176db5eemostang.com!davidm char *buf; 385de4b351e7624889db611e10dd3034e0176db5eemostang.com!davidm char *buf_end; 39b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov char *path; 40824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm }; 41824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm 4264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidmstatic inline char * 4364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidmltoa (char *buf, long val) 4464c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm{ 4564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm char *cp = buf, tmp; 4664c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm ssize_t i, len; 4764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 4864c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm do 4964c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm { 5064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm *cp++ = '0' + (val % 10); 5164c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm val /= 10; 5264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm } 5364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm while (val); 5464c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 5564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm /* reverse the order of the digits: */ 5664c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm len = cp - buf; 5764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm --cp; 5864c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm for (i = 0; i < len / 2; ++i) 5964c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm { 6064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm tmp = buf[i]; 6164c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm buf[i] = cp[-i]; 6264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm cp[-i] = tmp; 6364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm } 6464c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return buf + len; 6564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm} 6664c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 67b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikovstatic inline int 68824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmmaps_init (struct map_iterator *mi, pid_t pid) 69824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm{ 70b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov char path[sizeof ("/proc/0123456789/maps")], *cp; 71824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm 7264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm memcpy (path, "/proc/", 6); 7364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm cp = ltoa (path + 6, pid); 74b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov assert (cp + 6 < path + sizeof (path)); 7564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm memcpy (cp, "/maps", 6); 7664c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 7764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm mi->fd = open (path, O_RDONLY); 782f210753bd631692bd93f4d0a90e9195424075b9mostang.com!davidm if (mi->fd >= 0) 792f210753bd631692bd93f4d0a90e9195424075b9mostang.com!davidm { 80b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov /* Try to allocate a page-sized buffer. */ 812f210753bd631692bd93f4d0a90e9195424075b9mostang.com!davidm mi->buf_size = getpagesize (); 82890e23eb9d3ffd9be2a025189a21794b5ed0e0ffTommi Rantala cp = mmap (NULL, mi->buf_size, PROT_READ | PROT_WRITE, 832f210753bd631692bd93f4d0a90e9195424075b9mostang.com!davidm MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 842f210753bd631692bd93f4d0a90e9195424075b9mostang.com!davidm if (cp == MAP_FAILED) 856a072982ddd0b8c1597ac2aa17559732c8b5e763Zachary T Welch { 866a072982ddd0b8c1597ac2aa17559732c8b5e763Zachary T Welch close(mi->fd); 876a072982ddd0b8c1597ac2aa17559732c8b5e763Zachary T Welch mi->fd = -1; 886a072982ddd0b8c1597ac2aa17559732c8b5e763Zachary T Welch return -1; 896a072982ddd0b8c1597ac2aa17559732c8b5e763Zachary T Welch } 902f210753bd631692bd93f4d0a90e9195424075b9mostang.com!davidm else 91b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov { 92b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov mi->offset = 0; 93b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov mi->buf = mi->buf_end = cp + mi->buf_size; 94b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov return 0; 95b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov } 962f210753bd631692bd93f4d0a90e9195424075b9mostang.com!davidm } 97b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov return -1; 9864c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm} 9964c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 10064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidmstatic inline char * 10164c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidmskip_whitespace (char *cp) 10264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm{ 10364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm if (!cp) 10464c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return NULL; 10564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 10664c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm while (*cp == ' ' || *cp == '\t') 10764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm ++cp; 10864c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return cp; 10964c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm} 11064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 11164c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidmstatic inline char * 11264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidmscan_hex (char *cp, unsigned long *valp) 11364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm{ 11464c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm unsigned long num_digits = 0, digit, val = 0; 11564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 11664c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm cp = skip_whitespace (cp); 11764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm if (!cp) 11864c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return NULL; 11964c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 12064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm while (1) 12164c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm { 12264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm digit = *cp; 12364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm if ((digit - '0') <= 9) 12464c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm digit -= '0'; 12564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm else if ((digit - 'a') < 6) 12664c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm digit -= 'a' - 10; 12764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm else if ((digit - 'A') < 6) 12864c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm digit -= 'A' - 10; 12964c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm else 13064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm break; 13164c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm val = (val << 4) | digit; 13264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm ++num_digits; 13364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm ++cp; 13464c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm } 13564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm if (!num_digits) 13664c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return NULL; 13764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm *valp = val; 13864c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return cp; 13964c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm} 14064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 14164c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidmstatic inline char * 14264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidmscan_dec (char *cp, unsigned long *valp) 14364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm{ 14464c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm unsigned long num_digits = 0, digit, val = 0; 14564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 14664c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm if (!(cp = skip_whitespace (cp))) 14764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return NULL; 14864c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 14964c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm while (1) 15064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm { 1516c61288b9c5b3c967937d9ab12113bc7e368e433hp.com!davidm digit = *cp; 15264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm if ((digit - '0') <= 9) 1536c61288b9c5b3c967937d9ab12113bc7e368e433hp.com!davidm { 1546c61288b9c5b3c967937d9ab12113bc7e368e433hp.com!davidm digit -= '0'; 1556c61288b9c5b3c967937d9ab12113bc7e368e433hp.com!davidm ++cp; 1566c61288b9c5b3c967937d9ab12113bc7e368e433hp.com!davidm } 15764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm else 15864c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm break; 15964c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm val = (10 * val) + digit; 16064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm ++num_digits; 16164c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm } 16264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm if (!num_digits) 16364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return NULL; 16464c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm *valp = val; 16564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return cp; 16664c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm} 16764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 16864c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidmstatic inline char * 16964c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidmscan_char (char *cp, char *valp) 17064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm{ 17164c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm if (!cp) 17264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return NULL; 17364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 1746c61288b9c5b3c967937d9ab12113bc7e368e433hp.com!davidm *valp = *cp; 1756c61288b9c5b3c967937d9ab12113bc7e368e433hp.com!davidm 1766c61288b9c5b3c967937d9ab12113bc7e368e433hp.com!davidm /* don't step over NUL terminator */ 1776c61288b9c5b3c967937d9ab12113bc7e368e433hp.com!davidm if (*cp) 1786c61288b9c5b3c967937d9ab12113bc7e368e433hp.com!davidm ++cp; 17964c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return cp; 18064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm} 18164c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 18264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm/* Scan a string delimited by white-space. Fails on empty string or 18364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm if string is doesn't fit in the specified buffer. */ 18464c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidmstatic inline char * 18564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidmscan_string (char *cp, char *valp, size_t buf_size) 18664c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm{ 18764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm size_t i = 0; 18864c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 18964c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm if (!(cp = skip_whitespace (cp))) 19064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return NULL; 19164c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 19264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm while (*cp != ' ' && *cp != '\t' && *cp != '\0') 19364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm { 194b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov if ((valp != NULL) && (i < buf_size - 1)) 19564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm valp[i++] = *cp; 19664c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm ++cp; 19764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm } 19864c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm if (i == 0 || i >= buf_size) 19964c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return NULL; 20064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm valp[i] = '\0'; 20164c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return cp; 202824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm} 203824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm 204824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmstatic inline int 205824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmmaps_next (struct map_iterator *mi, 2067d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris unsigned long *low, unsigned long *high, unsigned long *offset, 2077d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris unsigned long *flags) 208824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm{ 209851f14281c2fefb596c8e6b2e356c553a3f5cc87Arun Sharma char perm[16], dash = 0, colon = 0, *cp; 21064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm unsigned long major, minor, inum; 21164c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm ssize_t i, nread; 212824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm 21364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm if (mi->fd < 0) 214824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm return 0; 215824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm 21664c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm while (1) 217824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm { 218b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov ssize_t bytes_left = mi->buf_end - mi->buf; 219b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov char *eol = NULL; 2205de4b351e7624889db611e10dd3034e0176db5eemostang.com!davidm 221b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov for (i = 0; i < bytes_left; ++i) 222b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov { 223b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov if (mi->buf[i] == '\n') 2245de4b351e7624889db611e10dd3034e0176db5eemostang.com!davidm { 225b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov eol = mi->buf + i; 226b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov break; 2275de4b351e7624889db611e10dd3034e0176db5eemostang.com!davidm } 228b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov else if (mi->buf[i] == '\0') 229b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov break; 23064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm } 231b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov if (!eol) 23264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm { 233b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov /* copy down the remaining bytes, if any */ 234b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov if (bytes_left > 0) 235b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov memmove (mi->buf_end - mi->buf_size, mi->buf, bytes_left); 236b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov 237b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov mi->buf = mi->buf_end - mi->buf_size; 238b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov nread = read (mi->fd, mi->buf + bytes_left, 239b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov mi->buf_size - bytes_left); 240b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov if (nread <= 0) 2415de4b351e7624889db611e10dd3034e0176db5eemostang.com!davidm return 0; 242b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov else if ((size_t) (nread + bytes_left) < mi->buf_size) 2435de4b351e7624889db611e10dd3034e0176db5eemostang.com!davidm { 244b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov /* Move contents to the end of the buffer so we 245b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov maintain the invariant that all bytes between 246b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov mi->buf and mi->buf_end are valid. */ 247b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov memmove (mi->buf_end - nread - bytes_left, mi->buf, 248b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov nread + bytes_left); 249b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov mi->buf = mi->buf_end - nread - bytes_left; 2505de4b351e7624889db611e10dd3034e0176db5eemostang.com!davidm } 251b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov 252b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov eol = mi->buf + bytes_left + nread - 1; 253b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov 254b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov for (i = bytes_left; i < bytes_left + nread; ++i) 255b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov if (mi->buf[i] == '\n') 256b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov { 257b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov eol = mi->buf + i; 258b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov break; 259b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov } 26064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm } 261b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov cp = mi->buf; 262b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov mi->buf = eol + 1; 263b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov *eol = '\0'; 26464c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm 26564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm /* scan: "LOW-HIGH PERM OFFSET MAJOR:MINOR INUM PATH" */ 2665de4b351e7624889db611e10dd3034e0176db5eemostang.com!davidm cp = scan_hex (cp, low); 26764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm cp = scan_char (cp, &dash); 26864c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm cp = scan_hex (cp, high); 26964c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm cp = scan_string (cp, perm, sizeof (perm)); 27064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm cp = scan_hex (cp, offset); 27164c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm cp = scan_hex (cp, &major); 27264c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm cp = scan_char (cp, &colon); 27364c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm cp = scan_hex (cp, &minor); 27464c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm cp = scan_dec (cp, &inum); 275b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov cp = mi->path = skip_whitespace (cp); 276b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov if (!cp) 277b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov continue; 278b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov cp = scan_string (cp, NULL, 0); 2795a1d3c6fd765e45b97f478c9db3a2d4cdaa75c69Arun Sharma if (dash != '-' || colon != ':') 28064c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm continue; /* skip line with unknown or bad format */ 2817d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris if (flags) 2827d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris { 2837d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris *flags = 0; 2847d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris if (perm[0] == 'r') 2857d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris { 2867d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris *flags |= PROT_READ; 2877d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris } 2887d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris if (perm[1] == 'w') 2897d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris { 2907d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris *flags |= PROT_WRITE; 2917d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris } 2927d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris if (perm[2] == 'x') 2937d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris { 2947d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris *flags |= PROT_EXEC; 2957d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris } 2967d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris } 29764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm return 1; 298824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm } 299824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm return 0; 300824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm} 301824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm 302824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmstatic inline void 303824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmmaps_close (struct map_iterator *mi) 304824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm{ 30564c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm if (mi->fd < 0) 306cfded02a05f7fd5314ca4619b53005955a60aceehp.com!davidm return; 30764c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm close (mi->fd); 30864c702cea7c2de53ff1ff93dfe76e065036b4e3emostang.com!davidm mi->fd = -1; 3092f210753bd631692bd93f4d0a90e9195424075b9mostang.com!davidm if (mi->buf) 3102f210753bd631692bd93f4d0a90e9195424075b9mostang.com!davidm { 3112f210753bd631692bd93f4d0a90e9195424075b9mostang.com!davidm munmap (mi->buf_end - mi->buf_size, mi->buf_size); 312890e23eb9d3ffd9be2a025189a21794b5ed0e0ffTommi Rantala mi->buf = mi->buf_end = NULL; 3132f210753bd631692bd93f4d0a90e9195424075b9mostang.com!davidm } 314824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm} 315824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm 316824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm#endif /* os_linux_h */ 317