]> git.saurik.com Git - apple/system_cmds.git/blame - gcore.tproj/utils.c
system_cmds-880.100.5.tar.gz
[apple/system_cmds.git] / gcore.tproj / utils.c
CommitLineData
cf37c299 1/*
887d5eed 2 * Copyright (c) 2016 Apple Inc. All rights reserved.
cf37c299
A
3 */
4
5#include "options.h"
6#include "utils.h"
7#include "region.h"
8
9#include <stdio.h>
10#include <string.h>
11#include <strings.h>
12#include <stdlib.h>
13#include <stdarg.h>
14#include <unistd.h>
15#include <libutil.h>
887d5eed 16#include <errno.h>
cf37c299
A
17
18void
19err_mach(kern_return_t kr, const struct region *r, const char *fmt, ...)
20{
21 va_list ap;
22 va_start(ap, fmt);
23 if (0 != kr)
24 printf("%s: ", pgm);
25 if (NULL != r)
887d5eed 26 printf("%016llx-%016llx ", R_ADDR(r), R_ENDADDR(r));
cf37c299
A
27 vprintf(fmt, ap);
28 va_end(ap);
29
30 if (0 != kr) {
887d5eed 31 printf(": failed: %s (0x%x)", mach_error_string(kr), kr);
cf37c299
A
32 switch (err_get_system(kr)) {
33 case err_get_system(err_mach_ipc):
34 /* 0x10000000 == (4 << 26) */
35 printf(" => fatal\n");
36 exit(127);
37 default:
38 putchar('\n');
39 break;
40 }
41 } else
42 putchar('\n');
43}
44
887d5eed
A
45static void
46vprintvr(const struct vm_range *vr, const char *restrict fmt, va_list ap)
47{
48 if (NULL != vr)
49 printf("%016llx-%016llx ", V_ADDR(vr), V_ENDADDR(vr));
50 vprintf(fmt, ap);
51}
52
53void
54printvr(const struct vm_range *vr, const char *fmt, ...)
55{
56 va_list ap;
57 va_start(ap, fmt);
58 vprintvr(vr, fmt, ap);
59 va_end(ap);
60}
61
cf37c299
A
62void
63printr(const struct region *r, const char *fmt, ...)
64{
65 va_list ap;
66 va_start(ap, fmt);
887d5eed 67 vprintvr(R_RANGE(r), fmt, ap);
cf37c299
A
68 va_end(ap);
69}
70
71/*
72 * Print power-of-1024 sizes in human-readable form
73 */
74const char *
75str_hsize(hsize_str_t hstr, uint64_t size)
76{
77 humanize_number(hstr, sizeof (hsize_str_t) - 1, size, "",
78 HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL | HN_IEC_PREFIXES);
79 return hstr;
80}
81
887d5eed
A
82/*
83 * Print VM protections in human-readable form
84 */
85const char *
86str_prot(const vm_prot_t prot)
87{
88 static const char *pstr[] = {
89 [0] = "---",
90 [VM_PROT_READ] = "r--",
91 [VM_PROT_WRITE] = "-w-",
92 [VM_PROT_READ|VM_PROT_WRITE] = "rw-",
93 [VM_PROT_EXECUTE] = "--x",
94 [VM_PROT_READ|VM_PROT_EXECUTE] = "r-x",
95 [VM_PROT_WRITE|VM_PROT_EXECUTE] = "-wx",
96 [VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE] = "rwx"
97 };
98 return pstr[prot & 7];
99}
100
101// c.f. VMUVMRegion.m
102
103const char *
104str_shared(int sm)
105{
106 static const char *sstr[] = {
107 [0] = " ",
108 [SM_COW] = "sm=cow",
109 [SM_PRIVATE] = "sm=prv",
110 [SM_EMPTY] = "sm=nul",
111 [SM_SHARED] = "sm=ali",
112 [SM_TRUESHARED] = "sm=shm",
113 [SM_PRIVATE_ALIASED] = "sm=zer",
114 [SM_SHARED_ALIASED] = "sm=s/a",
115 [SM_LARGE_PAGE] = "sm=lpg",
116 };
117 if ((unsigned)sm < sizeof (sstr) / sizeof (sstr[0]))
118 return sstr[sm];
119 return "sm=???";
120}
121
122const char *
123str_purgable(int pu, int sm)
124{
125 if (SM_EMPTY == sm)
126 return " ";
127 static const char *pstr[] = {
128 [VM_PURGABLE_NONVOLATILE] = "p=n",
129 [VM_PURGABLE_VOLATILE] = "p=v",
130 [VM_PURGABLE_EMPTY] = "p=e",
131 [VM_PURGABLE_DENY] = " ",
132 };
133 if ((unsigned)pu < sizeof (pstr) / sizeof (pstr[0]))
134 return pstr[pu];
135 return "p=?";
136}
137
138/*
139 * c.f. VMURegionTypeDescriptionForTagShareProtAndPager.
140 */
141const char *
142str_tag(tag_str_t tstr, int tag, int share_mode, vm_prot_t curprot, int external_pager)
143{
144 const char *rtype;
145
146 switch (tag) {
147 case 0:
148 if (external_pager)
149 rtype = "mapped file";
150 else if (SM_TRUESHARED == share_mode)
151 rtype = "shared memory";
152 else
153 rtype = "VM_allocate";
154 break;
155 case VM_MEMORY_MALLOC:
156 if (VM_PROT_NONE == curprot)
157 rtype = "MALLOC guard page";
158 else if (SM_EMPTY == share_mode)
159 rtype = "MALLOC";
160 else
161 rtype = "MALLOC metadata";
162 break;
163 case VM_MEMORY_STACK:
164 if (VM_PROT_NONE == curprot)
165 rtype = "Stack guard";
166 else
167 rtype = "Stack";
168 break;
169#if defined(CONFIG_DEBUG) || defined(CONFIG_GCORE_MAP)
170 case VM_MEMORY_MALLOC_SMALL:
171 rtype = "MALLOC_SMALL";
172 break;
173 case VM_MEMORY_MALLOC_LARGE:
174 rtype = "MALLOC_LARGE";
175 break;
176 case VM_MEMORY_MALLOC_HUGE:
177 rtype = "MALLOC_HUGE";
178 break;
179 case VM_MEMORY_SBRK:
180 rtype = "SBRK";
181 break;
182 case VM_MEMORY_REALLOC:
183 rtype = "MALLOC_REALLOC";
184 break;
185 case VM_MEMORY_MALLOC_TINY:
186 rtype = "MALLOC_TINY";
187 break;
188 case VM_MEMORY_MALLOC_LARGE_REUSABLE:
189 rtype = "MALLOC_LARGE_REUSABLE";
190 break;
191 case VM_MEMORY_MALLOC_LARGE_REUSED:
192 rtype = "MALLOC_LARGE";
193 break;
194 case VM_MEMORY_ANALYSIS_TOOL:
195 rtype = "Performance tool data";
196 break;
197 case VM_MEMORY_MALLOC_NANO:
198 rtype = "MALLOC_NANO";
199 break;
200 case VM_MEMORY_MACH_MSG:
201 rtype = "Mach message";
202 break;
203 case VM_MEMORY_IOKIT:
204 rtype = "IOKit";
205 break;
206 case VM_MEMORY_GUARD:
207 rtype = "Guard";
208 break;
209 case VM_MEMORY_SHARED_PMAP:
210 rtype = "shared pmap";
211 break;
212 case VM_MEMORY_DYLIB:
213 rtype = "dylib";
214 break;
215 case VM_MEMORY_OBJC_DISPATCHERS:
216 rtype = "ObjC dispatching code";
217 break;
218 case VM_MEMORY_UNSHARED_PMAP:
219 rtype = "unshared pmap";
220 break;
221 case VM_MEMORY_APPKIT:
222 rtype = "AppKit";
223 break;
224 case VM_MEMORY_FOUNDATION:
225 rtype = "Foundation";
226 break;
227 case VM_MEMORY_COREGRAPHICS:
228 rtype = "CoreGraphics";
229 break;
230 case VM_MEMORY_CORESERVICES:
231 rtype = "CoreServices";
232 break;
233 case VM_MEMORY_JAVA:
234 rtype = "Java";
235 break;
236 case VM_MEMORY_COREDATA:
237 rtype = "CoreData";
238 break;
239 case VM_MEMORY_COREDATA_OBJECTIDS:
240 rtype = "CoreData Object IDs";
241 break;
242 case VM_MEMORY_ATS:
243 rtype = "ATS (font support)";
244 break;
245 case VM_MEMORY_LAYERKIT:
246 rtype = "CoreAnimation";
247 break;
248 case VM_MEMORY_CGIMAGE:
249 rtype = "CG image";
250 break;
251 case VM_MEMORY_TCMALLOC:
252 rtype = "WebKit Malloc";
253 break;
254 case VM_MEMORY_COREGRAPHICS_DATA:
255 rtype = "CG raster data";
256 break;
257 case VM_MEMORY_COREGRAPHICS_SHARED:
258 rtype = "CG shared images";
259 break;
260 case VM_MEMORY_COREGRAPHICS_FRAMEBUFFERS:
261 rtype = "CG framebuffers";
262 break;
263 case VM_MEMORY_COREGRAPHICS_BACKINGSTORES:
264 rtype = "CG backingstores";
265 break;
266 case VM_MEMORY_DYLD:
267 rtype = "dyld private memory";
268 break;
269 case VM_MEMORY_DYLD_MALLOC:
270 rtype = "dyld malloc memory";
271 break;
272 case VM_MEMORY_SQLITE:
273 rtype = "SQlite page cache";
274 break;
275 case VM_MEMORY_JAVASCRIPT_CORE:
276 rtype = "WebAssembly memory";
277 break;
278 case VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR:
279 rtype = "JS JIT generated code";
280 break;
281 case VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE:
282 rtype = "JS VM register file";
283 break;
284 case VM_MEMORY_GLSL:
285 rtype = "OpenGL GLSL";
286 break;
287 case VM_MEMORY_OPENCL:
288 rtype = "OpenCL";
289 break;
290 case VM_MEMORY_COREIMAGE:
291 rtype = "CoreImage";
292 break;
293 case VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS:
294 rtype = "WebCore purgable data";
295 break;
296 case VM_MEMORY_IMAGEIO:
297 rtype = "Image IO";
298 break;
299 case VM_MEMORY_COREPROFILE:
300 rtype = "CoreProfile";
301 break;
302 case VM_MEMORY_ASSETSD:
303 rtype = "Assets Library";
304 break;
305 case VM_MEMORY_OS_ALLOC_ONCE:
306 rtype = "OS Alloc Once";
307 break;
308 case VM_MEMORY_LIBDISPATCH:
309 rtype = "Dispatch continuations";
310 break;
311 case VM_MEMORY_ACCELERATE:
312 rtype = "Accelerate framework";
313 break;
314 case VM_MEMORY_COREUI:
315 rtype = "CoreUI image data";
316 break;
317 case VM_MEMORY_COREUIFILE:
318 rtype = "CoreUI image file";
319 break;
320 case VM_MEMORY_GENEALOGY:
321 rtype = "Activity Tracing";
322 break;
323 case VM_MEMORY_RAWCAMERA:
324 rtype = "RawCamera";
325 break;
326 case VM_MEMORY_CORPSEINFO:
327 rtype = "Process Corpse Info";
328 break;
329 case VM_MEMORY_ASL:
330 rtype = "Apple System Log";
331 break;
332 case VM_MEMORY_SWIFT_RUNTIME:
333 rtype = "Swift runtime";
334 break;
335 case VM_MEMORY_SWIFT_METADATA:
336 rtype = "Swift metadata";
337 break;
338 case VM_MEMORY_DHMM:
339 rtype = "DHMM";
340 break;
341 case VM_MEMORY_SCENEKIT:
342 rtype = "SceneKit";
343 break;
344 case VM_MEMORY_SKYWALK:
345 rtype = "Skywalk Networking";
346 break;
347#endif
348 default:
349 rtype = NULL;
350 break;
351 }
352 if (rtype)
353 snprintf(tstr, sizeof (tag_str_t), "%s", rtype);
354 else
355 snprintf(tstr, sizeof (tag_str_t), "tag #%d", tag);
356 return tstr;
357}
358
359const char *
360str_tagr(tag_str_t tstr, const struct region *r) {
361 return str_tag(tstr, r->r_info.user_tag, r->r_info.share_mode, r->r_info.protection, r->r_info.external_pager);
362}
363
cf37c299
A
364/*
365 * Put two strings together separated by a '+' sign
887d5eed 366 * If the string gets too long, then add an ellipsis and
cf37c299
A
367 * stop concatenating it.
368 */
369char *
370strconcat(const char *s0, const char *s1, size_t maxlen)
371{
372 const char ellipsis[] = "...";
373 const char junction[] = ", ";
374 const size_t s0len = strlen(s0);
375 size_t nmlen = s0len + strlen(s1) + strlen(junction) + 1;
376 if (maxlen > strlen(ellipsis) && nmlen > maxlen) {
377 if (strcmp(s0 + s0len - strlen(ellipsis), ellipsis) == 0)
378 return strdup(s0);
379 s1 = ellipsis;
380 nmlen = s0len + strlen(s1) + strlen(junction) + 1;
381 }
382 char *p = malloc(nmlen);
383 if (p) {
384 strlcpy(p, s0, nmlen);
385 strlcat(p, junction, nmlen);
386 strlcat(p, s1, nmlen);
387 }
388 return p;
389}
887d5eed
A
390
391unsigned long
392simple_namehash(const char *nm)
393{
394 unsigned long result = 5381;
395 int c;
396 while (0 != (c = *nm++))
397 result = (result * 33) ^ c;
398 return result; /* modified djb2 */
399}
400
401int
402bounded_pwrite(int fd, const void *addr, size_t size, off_t off, bool *nocache, ssize_t *nwrittenp)
403{
404 if (opt->sizebound && off + (off_t)size > opt->sizebound)
405 return EFBIG;
406
407 bool oldnocache = *nocache;
408 if (size >= opt->ncthresh && !oldnocache)
409 *nocache = 0 == fcntl(fd, F_NOCACHE, 1);
410 else if (size < opt->ncthresh && oldnocache)
411 *nocache = 0 != fcntl(fd, F_NOCACHE, 0);
412 if (OPTIONS_DEBUG(opt, 3) && oldnocache ^ *nocache)
413 printf("F_NOCACHE now %sabled on fd %d\n", *nocache ? "en" : "dis", fd);
414
415 const ssize_t nwritten = pwrite(fd, addr, size, off);
416 if (-1 == nwritten)
417 return errno;
418 if (nwrittenp)
419 *nwrittenp = nwritten;
420 return 0;
421}