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