]>
Commit | Line | Data |
---|---|---|
959ef981 | 1 | // SPDX-License-Identifier: GPL-2.0 |
0bba1a49 | 2 | /* |
da23017d NS |
3 | * Copyright (c) 2004-2005 Silicon Graphics, Inc. |
4 | * All Rights Reserved. | |
0bba1a49 NS |
5 | */ |
6 | ||
6b803e5a CH |
7 | #include "command.h" |
8 | #include "input.h" | |
0bba1a49 | 9 | #include <sys/mman.h> |
0bba1a49 NS |
10 | #include "init.h" |
11 | #include "io.h" | |
12 | ||
13 | static cmdinfo_t mincore_cmd; | |
14 | ||
00ff2b10 | 15 | static int |
0bba1a49 NS |
16 | mincore_f( |
17 | int argc, | |
18 | char **argv) | |
19 | { | |
3b1cdc9f | 20 | off64_t offset, llength; |
0bba1a49 | 21 | size_t length; |
2c2f6d79 | 22 | size_t blocksize, sectsize; |
0bba1a49 NS |
23 | void *start; |
24 | void *current, *previous; | |
25 | unsigned char *vec; | |
cb7ba2b0 | 26 | int i; |
0bba1a49 NS |
27 | |
28 | if (argc == 1) { | |
29 | offset = mapping->offset; | |
30 | length = mapping->length; | |
31 | } else if (argc == 3) { | |
32 | init_cvtnum(&blocksize, §size); | |
33 | offset = cvtnum(blocksize, sectsize, argv[1]); | |
34 | if (offset < 0) { | |
35 | printf(_("non-numeric offset argument -- %s\n"), | |
36 | argv[1]); | |
37 | return 0; | |
38 | } | |
3b1cdc9f ES |
39 | llength = cvtnum(blocksize, sectsize, argv[2]); |
40 | if (llength < 0) { | |
0bba1a49 NS |
41 | printf(_("non-numeric length argument -- %s\n"), |
42 | argv[2]); | |
43 | return 0; | |
3b1cdc9f ES |
44 | } else if (llength > (size_t)llength) { |
45 | printf(_("length argument too large -- %lld\n"), | |
1accf98c | 46 | (long long)llength); |
3b1cdc9f ES |
47 | return 0; |
48 | } else | |
49 | length = (size_t)llength; | |
0bba1a49 NS |
50 | } else { |
51 | return command_usage(&mincore_cmd); | |
52 | } | |
53 | ||
54 | start = check_mapping_range(mapping, offset, length, 1); | |
55 | if (!start) | |
56 | return 0; | |
57 | ||
58 | vec = calloc(length/pagesize, sizeof(unsigned char)); | |
59 | if (!vec) { | |
60 | perror("calloc"); | |
61 | return 0; | |
62 | } | |
63 | ||
64 | if (mincore(start, length, vec) < 0) { | |
65 | perror("mincore"); | |
66 | free(vec); | |
67 | return 0; | |
68 | } | |
69 | ||
70 | previous = NULL; | |
71 | current = start; | |
72 | for (i = 0; i < length/pagesize; i++, current += pagesize) { | |
73 | if (vec[i]) { | |
74 | if (!previous) { /* print start address */ | |
75 | printf("0x%lx - ", (unsigned long)current); | |
76 | previous = start + (i * pagesize); | |
77 | } | |
78 | } else if (previous) { /* print end and page count */ | |
79 | printf(_("0x%lx %lu pages (%llu : %lu)\n"), | |
80 | (unsigned long)current, | |
81 | (unsigned long)(current - previous) / pagesize, | |
82 | (unsigned long long)offset + | |
83 | (unsigned long long)(previous - start), | |
84 | (unsigned long)(current - previous)); | |
85 | previous = NULL; | |
86 | } | |
87 | } | |
88 | if (previous) | |
89 | printf(_("0x%lx %lu pages (%llu : %lu)\n"), | |
90 | (unsigned long)current, | |
91 | (unsigned long)(current - previous) / pagesize, | |
92 | (unsigned long long)offset + | |
93 | (unsigned long long)(previous - start), | |
94 | (unsigned long)(current - previous)); | |
95 | ||
96 | free(vec); | |
97 | return 0; | |
98 | } | |
99 | ||
100 | void | |
101 | mincore_init(void) | |
102 | { | |
ad765595 AM |
103 | mincore_cmd.name = "mincore"; |
104 | mincore_cmd.altname = "mi"; | |
0bba1a49 NS |
105 | mincore_cmd.cfunc = mincore_f; |
106 | mincore_cmd.argmin = 0; | |
107 | mincore_cmd.argmax = 2; | |
108 | mincore_cmd.flags = CMD_NOFILE_OK | CMD_FOREIGN_OK; | |
109 | mincore_cmd.args = _("[off len]"); | |
110 | mincore_cmd.oneline = _("find mapping pages that are memory resident"); | |
111 | ||
112 | add_command(&mincore_cmd); | |
113 | } |