1 #include "../perf.h" 2 #include "util.h" 3 #include <sys/mman.h> 4 #ifdef BACKTRACE_SUPPORT 5 #include <execinfo.h> 6 #endif 7 #include <stdio.h> 8 #include <stdlib.h> 9 10 /* 11 * XXX We need to find a better place for these things... 12 */ 13 unsigned int page_size; 14 15 bool perf_host = true; 16 bool perf_guest = false; 17 18 void event_attr_init(struct perf_event_attr *attr) 19 { 20 if (!perf_host) 21 attr->exclude_host = 1; 22 if (!perf_guest) 23 attr->exclude_guest = 1; 24 /* to capture ABI version */ 25 attr->size = sizeof(*attr); 26 } 27 28 int mkdir_p(char *path, mode_t mode) 29 { 30 struct stat st; 31 int err; 32 char *d = path; 33 34 if (*d != '/') 35 return -1; 36 37 if (stat(path, &st) == 0) 38 return 0; 39 40 while (*++d == '/'); 41 42 while ((d = strchr(d, '/'))) { 43 *d = '\0'; 44 err = stat(path, &st) && mkdir(path, mode); 45 *d++ = '/'; 46 if (err) 47 return -1; 48 while (*d == '/') 49 ++d; 50 } 51 return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0; 52 } 53 54 static int slow_copyfile(const char *from, const char *to) 55 { 56 int err = 0; 57 char *line = NULL; 58 size_t n; 59 FILE *from_fp = fopen(from, "r"), *to_fp; 60 61 if (from_fp == NULL) 62 goto out; 63 64 to_fp = fopen(to, "w"); 65 if (to_fp == NULL) 66 goto out_fclose_from; 67 68 while (getline(&line, &n, from_fp) > 0) 69 if (fputs(line, to_fp) == EOF) 70 goto out_fclose_to; 71 err = 0; 72 out_fclose_to: 73 fclose(to_fp); 74 free(line); 75 out_fclose_from: 76 fclose(from_fp); 77 out: 78 return err; 79 } 80 81 int copyfile(const char *from, const char *to) 82 { 83 int fromfd, tofd; 84 struct stat st; 85 void *addr; 86 int err = -1; 87 88 if (stat(from, &st)) 89 goto out; 90 91 if (st.st_size == 0) /* /proc? do it slowly... */ 92 return slow_copyfile(from, to); 93 94 fromfd = open(from, O_RDONLY); 95 if (fromfd < 0) 96 goto out; 97 98 tofd = creat(to, 0755); 99 if (tofd < 0) 100 goto out_close_from; 101 102 addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fromfd, 0); 103 if (addr == MAP_FAILED) 104 goto out_close_to; 105 106 if (write(tofd, addr, st.st_size) == st.st_size) 107 err = 0; 108 109 munmap(addr, st.st_size); 110 out_close_to: 111 close(tofd); 112 if (err) 113 unlink(to); 114 out_close_from: 115 close(fromfd); 116 out: 117 return err; 118 } 119 120 unsigned long convert_unit(unsigned long value, char *unit) 121 { 122 *unit = ' '; 123 124 if (value > 1000) { 125 value /= 1000; 126 *unit = 'K'; 127 } 128 129 if (value > 1000) { 130 value /= 1000; 131 *unit = 'M'; 132 } 133 134 if (value > 1000) { 135 value /= 1000; 136 *unit = 'G'; 137 } 138 139 return value; 140 } 141 142 int readn(int fd, void *buf, size_t n) 143 { 144 void *buf_start = buf; 145 146 while (n) { 147 int ret = read(fd, buf, n); 148 149 if (ret <= 0) 150 return ret; 151 152 n -= ret; 153 buf += ret; 154 } 155 156 return buf - buf_start; 157 } 158 159 size_t hex_width(u64 v) 160 { 161 size_t n = 1; 162 163 while ((v >>= 4)) 164 ++n; 165 166 return n; 167 } 168 169 static int hex(char ch) 170 { 171 if ((ch >= '0') && (ch <= '9')) 172 return ch - '0'; 173 if ((ch >= 'a') && (ch <= 'f')) 174 return ch - 'a' + 10; 175 if ((ch >= 'A') && (ch <= 'F')) 176 return ch - 'A' + 10; 177 return -1; 178 } 179 180 /* 181 * While we find nice hex chars, build a long_val. 182 * Return number of chars processed. 183 */ 184 int hex2u64(const char *ptr, u64 *long_val) 185 { 186 const char *p = ptr; 187 *long_val = 0; 188 189 while (*p) { 190 const int hex_val = hex(*p); 191 192 if (hex_val < 0) 193 break; 194 195 *long_val = (*long_val << 4) | hex_val; 196 p++; 197 } 198 199 return p - ptr; 200 } 201 202 /* Obtain a backtrace and print it to stdout. */ 203 #ifdef BACKTRACE_SUPPORT 204 void dump_stack(void) 205 { 206 void *array[16]; 207 size_t size = backtrace(array, ARRAY_SIZE(array)); 208 char **strings = backtrace_symbols(array, size); 209 size_t i; 210 211 printf("Obtained %zd stack frames.\n", size); 212 213 for (i = 0; i < size; i++) 214 printf("%s\n", strings[i]); 215 216 free(strings); 217 } 218 #else 219 void dump_stack(void) {} 220 #endif 221