Commit | Line | Data |
---|---|---|
ddc98fbf JK |
1 | /* Linux-specific memory maps manipulation routines. |
2 | Copyright (C) 2015 Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of GDB. | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 3 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
18 | ||
19 | #include "common-defs.h" | |
20 | #include "linux-maps.h" | |
9904185c JK |
21 | #include <ctype.h> |
22 | #include "target/target-utils.h" | |
23 | #include "gdb_regex.h" | |
24 | #include "target/target.h" | |
25 | ||
26 | /* This struct is used to map flags found in the "VmFlags:" field (in | |
27 | the /proc/<PID>/smaps file). */ | |
28 | ||
29 | struct smaps_vmflags | |
30 | { | |
31 | /* Zero if this structure has not been initialized yet. It | |
32 | probably means that the Linux kernel being used does not emit | |
33 | the "VmFlags:" field on "/proc/PID/smaps". */ | |
34 | ||
35 | unsigned int initialized_p : 1; | |
36 | ||
37 | /* Memory mapped I/O area (VM_IO, "io"). */ | |
38 | ||
39 | unsigned int io_page : 1; | |
40 | ||
41 | /* Area uses huge TLB pages (VM_HUGETLB, "ht"). */ | |
42 | ||
43 | unsigned int uses_huge_tlb : 1; | |
44 | ||
45 | /* Do not include this memory region on the coredump (VM_DONTDUMP, "dd"). */ | |
46 | ||
47 | unsigned int exclude_coredump : 1; | |
48 | ||
49 | /* Is this a MAP_SHARED mapping (VM_SHARED, "sh"). */ | |
50 | ||
51 | unsigned int shared_mapping : 1; | |
52 | }; | |
53 | ||
54 | /* Service function for corefiles and info proc. */ | |
55 | ||
56 | void | |
57 | read_mapping (const char *line, | |
58 | ULONGEST *addr, ULONGEST *endaddr, | |
59 | const char **permissions, size_t *permissions_len, | |
60 | ULONGEST *offset, | |
61 | const char **device, size_t *device_len, | |
62 | ULONGEST *inode, | |
63 | const char **filename) | |
64 | { | |
65 | const char *p = line; | |
66 | ||
67 | *addr = strtoulst (p, &p, 16); | |
68 | if (*p == '-') | |
69 | p++; | |
70 | *endaddr = strtoulst (p, &p, 16); | |
71 | ||
72 | p = skip_spaces_const (p); | |
73 | *permissions = p; | |
74 | while (*p && !isspace (*p)) | |
75 | p++; | |
76 | *permissions_len = p - *permissions; | |
77 | ||
78 | *offset = strtoulst (p, &p, 16); | |
79 | ||
80 | p = skip_spaces_const (p); | |
81 | *device = p; | |
82 | while (*p && !isspace (*p)) | |
83 | p++; | |
84 | *device_len = p - *device; | |
85 | ||
86 | *inode = strtoulst (p, &p, 10); | |
87 | ||
88 | p = skip_spaces_const (p); | |
89 | *filename = p; | |
90 | } | |
91 | ||
92 | /* Helper function to decode the "VmFlags" field in /proc/PID/smaps. | |
93 | ||
94 | This function was based on the documentation found on | |
95 | <Documentation/filesystems/proc.txt>, on the Linux kernel. | |
96 | ||
97 | Linux kernels before commit | |
98 | 834f82e2aa9a8ede94b17b656329f850c1471514 (3.10) do not have this | |
99 | field on smaps. */ | |
100 | ||
101 | static void | |
102 | decode_vmflags (char *p, struct smaps_vmflags *v) | |
103 | { | |
104 | char *saveptr = NULL; | |
105 | const char *s; | |
106 | ||
107 | v->initialized_p = 1; | |
108 | p = skip_to_space (p); | |
109 | p = skip_spaces (p); | |
110 | ||
111 | for (s = strtok_r (p, " ", &saveptr); | |
112 | s != NULL; | |
113 | s = strtok_r (NULL, " ", &saveptr)) | |
114 | { | |
115 | if (strcmp (s, "io") == 0) | |
116 | v->io_page = 1; | |
117 | else if (strcmp (s, "ht") == 0) | |
118 | v->uses_huge_tlb = 1; | |
119 | else if (strcmp (s, "dd") == 0) | |
120 | v->exclude_coredump = 1; | |
121 | else if (strcmp (s, "sh") == 0) | |
122 | v->shared_mapping = 1; | |
123 | } | |
124 | } | |
125 | ||
126 | /* Return 1 if the memory mapping is anonymous, 0 otherwise. | |
127 | ||
128 | FILENAME is the name of the file present in the first line of the | |
129 | memory mapping, in the "/proc/PID/smaps" output. For example, if | |
130 | the first line is: | |
131 | ||
132 | 7fd0ca877000-7fd0d0da0000 r--p 00000000 fd:02 2100770 /path/to/file | |
133 | ||
134 | Then FILENAME will be "/path/to/file". */ | |
135 | ||
136 | static int | |
137 | mapping_is_anonymous_p (const char *filename) | |
138 | { | |
139 | static regex_t dev_zero_regex, shmem_file_regex, file_deleted_regex; | |
140 | static int init_regex_p = 0; | |
141 | ||
142 | if (!init_regex_p) | |
143 | { | |
144 | struct cleanup *c = make_cleanup (null_cleanup, NULL); | |
145 | ||
146 | /* Let's be pessimistic and assume there will be an error while | |
147 | compiling the regex'es. */ | |
148 | init_regex_p = -1; | |
149 | ||
150 | /* DEV_ZERO_REGEX matches "/dev/zero" filenames (with or | |
151 | without the "(deleted)" string in the end). We know for | |
152 | sure, based on the Linux kernel code, that memory mappings | |
153 | whose associated filename is "/dev/zero" are guaranteed to be | |
154 | MAP_ANONYMOUS. */ | |
155 | compile_rx_or_error (&dev_zero_regex, "^/dev/zero\\( (deleted)\\)\\?$", | |
156 | _("Could not compile regex to match /dev/zero " | |
157 | "filename")); | |
158 | /* SHMEM_FILE_REGEX matches "/SYSV%08x" filenames (with or | |
159 | without the "(deleted)" string in the end). These filenames | |
160 | refer to shared memory (shmem), and memory mappings | |
161 | associated with them are MAP_ANONYMOUS as well. */ | |
162 | compile_rx_or_error (&shmem_file_regex, | |
163 | "^/\\?SYSV[0-9a-fA-F]\\{8\\}\\( (deleted)\\)\\?$", | |
164 | _("Could not compile regex to match shmem " | |
165 | "filenames")); | |
166 | /* FILE_DELETED_REGEX is a heuristic we use to try to mimic the | |
167 | Linux kernel's 'n_link == 0' code, which is responsible to | |
168 | decide if it is dealing with a 'MAP_SHARED | MAP_ANONYMOUS' | |
169 | mapping. In other words, if FILE_DELETED_REGEX matches, it | |
170 | does not necessarily mean that we are dealing with an | |
171 | anonymous shared mapping. However, there is no easy way to | |
172 | detect this currently, so this is the best approximation we | |
173 | have. | |
174 | ||
175 | As a result, GDB will dump readonly pages of deleted | |
176 | executables when using the default value of coredump_filter | |
177 | (0x33), while the Linux kernel will not dump those pages. | |
178 | But we can live with that. */ | |
179 | compile_rx_or_error (&file_deleted_regex, " (deleted)$", | |
180 | _("Could not compile regex to match " | |
181 | "'<file> (deleted)'")); | |
182 | /* We will never release these regexes, so just discard the | |
183 | cleanups. */ | |
184 | discard_cleanups (c); | |
185 | ||
186 | /* If we reached this point, then everything succeeded. */ | |
187 | init_regex_p = 1; | |
188 | } | |
189 | ||
190 | if (init_regex_p == -1) | |
191 | { | |
192 | const char deleted[] = " (deleted)"; | |
193 | size_t del_len = sizeof (deleted) - 1; | |
194 | size_t filename_len = strlen (filename); | |
195 | ||
196 | /* There was an error while compiling the regex'es above. In | |
197 | order to try to give some reliable information to the caller, | |
198 | we just try to find the string " (deleted)" in the filename. | |
199 | If we managed to find it, then we assume the mapping is | |
200 | anonymous. */ | |
201 | return (filename_len >= del_len | |
202 | && strcmp (filename + filename_len - del_len, deleted) == 0); | |
203 | } | |
204 | ||
205 | if (*filename == '\0' | |
206 | || regexec (&dev_zero_regex, filename, 0, NULL, 0) == 0 | |
207 | || regexec (&shmem_file_regex, filename, 0, NULL, 0) == 0 | |
208 | || regexec (&file_deleted_regex, filename, 0, NULL, 0) == 0) | |
209 | return 1; | |
210 | ||
211 | return 0; | |
212 | } | |
213 | ||
214 | /* Return 0 if the memory mapping (which is related to FILTERFLAGS, V, | |
215 | MAYBE_PRIVATE_P, and MAPPING_ANONYMOUS_P) should not be dumped, or | |
216 | greater than 0 if it should. | |
217 | ||
218 | In a nutshell, this is the logic that we follow in order to decide | |
219 | if a mapping should be dumped or not. | |
220 | ||
221 | - If the mapping is associated to a file whose name ends with | |
222 | " (deleted)", or if the file is "/dev/zero", or if it is | |
223 | "/SYSV%08x" (shared memory), or if there is no file associated | |
224 | with it, or if the AnonHugePages: or the Anonymous: fields in the | |
225 | /proc/PID/smaps have contents, then GDB considers this mapping to | |
226 | be anonymous. Otherwise, GDB considers this mapping to be a | |
227 | file-backed mapping (because there will be a file associated with | |
228 | it). | |
229 | ||
230 | It is worth mentioning that, from all those checks described | |
231 | above, the most fragile is the one to see if the file name ends | |
232 | with " (deleted)". This does not necessarily mean that the | |
233 | mapping is anonymous, because the deleted file associated with | |
234 | the mapping may have been a hard link to another file, for | |
235 | example. The Linux kernel checks to see if "i_nlink == 0", but | |
236 | GDB cannot easily (and normally) do this check (iff running as | |
237 | root, it could find the mapping in /proc/PID/map_files/ and | |
238 | determine whether there still are other hard links to the | |
239 | inode/file). Therefore, we made a compromise here, and we assume | |
240 | that if the file name ends with " (deleted)", then the mapping is | |
241 | indeed anonymous. FWIW, this is something the Linux kernel could | |
242 | do better: expose this information in a more direct way. | |
243 | ||
244 | - If we see the flag "sh" in the "VmFlags:" field (in | |
245 | /proc/PID/smaps), then certainly the memory mapping is shared | |
246 | (VM_SHARED). If we have access to the VmFlags, and we don't see | |
247 | the "sh" there, then certainly the mapping is private. However, | |
248 | Linux kernels before commit | |
249 | 834f82e2aa9a8ede94b17b656329f850c1471514 (3.10) do not have the | |
250 | "VmFlags:" field; in that case, we use another heuristic: if we | |
251 | see 'p' in the permission flags, then we assume that the mapping | |
252 | is private, even though the presence of the 's' flag there would | |
253 | mean VM_MAYSHARE, which means the mapping could still be private. | |
254 | This should work OK enough, however. */ | |
255 | ||
256 | static int | |
257 | dump_mapping_p (enum filterflags filterflags, const struct smaps_vmflags *v, | |
258 | int maybe_private_p, int mapping_anon_p, int mapping_file_p, | |
259 | const char *filename) | |
260 | { | |
261 | /* Initially, we trust in what we received from our caller. This | |
262 | value may not be very precise (i.e., it was probably gathered | |
263 | from the permission line in the /proc/PID/smaps list, which | |
264 | actually refers to VM_MAYSHARE, and not VM_SHARED), but it is | |
265 | what we have until we take a look at the "VmFlags:" field | |
266 | (assuming that the version of the Linux kernel being used | |
267 | supports it, of course). */ | |
268 | int private_p = maybe_private_p; | |
269 | ||
270 | /* We always dump vDSO and vsyscall mappings, because it's likely that | |
271 | there'll be no file to read the contents from at core load time. | |
272 | The kernel does the same. */ | |
273 | if (strcmp ("[vdso]", filename) == 0 | |
274 | || strcmp ("[vsyscall]", filename) == 0) | |
275 | return 1; | |
276 | ||
277 | if (v->initialized_p) | |
278 | { | |
279 | /* We never dump I/O mappings. */ | |
280 | if (v->io_page) | |
281 | return 0; | |
282 | ||
283 | /* Check if we should exclude this mapping. */ | |
284 | if (v->exclude_coredump) | |
285 | return 0; | |
286 | ||
287 | /* Update our notion of whether this mapping is shared or | |
288 | private based on a trustworthy value. */ | |
289 | private_p = !v->shared_mapping; | |
290 | ||
291 | /* HugeTLB checking. */ | |
292 | if (v->uses_huge_tlb) | |
293 | { | |
294 | if ((private_p && (filterflags & COREFILTER_HUGETLB_PRIVATE)) | |
295 | || (!private_p && (filterflags & COREFILTER_HUGETLB_SHARED))) | |
296 | return 1; | |
297 | ||
298 | return 0; | |
299 | } | |
300 | } | |
301 | ||
302 | if (private_p) | |
303 | { | |
304 | if (mapping_anon_p && mapping_file_p) | |
305 | { | |
306 | /* This is a special situation. It can happen when we see a | |
307 | mapping that is file-backed, but that contains anonymous | |
308 | pages. */ | |
309 | return ((filterflags & COREFILTER_ANON_PRIVATE) != 0 | |
310 | || (filterflags & COREFILTER_MAPPED_PRIVATE) != 0); | |
311 | } | |
312 | else if (mapping_anon_p) | |
313 | return (filterflags & COREFILTER_ANON_PRIVATE) != 0; | |
314 | else | |
315 | return (filterflags & COREFILTER_MAPPED_PRIVATE) != 0; | |
316 | } | |
317 | else | |
318 | { | |
319 | if (mapping_anon_p && mapping_file_p) | |
320 | { | |
321 | /* This is a special situation. It can happen when we see a | |
322 | mapping that is file-backed, but that contains anonymous | |
323 | pages. */ | |
324 | return ((filterflags & COREFILTER_ANON_SHARED) != 0 | |
325 | || (filterflags & COREFILTER_MAPPED_SHARED) != 0); | |
326 | } | |
327 | else if (mapping_anon_p) | |
328 | return (filterflags & COREFILTER_ANON_SHARED) != 0; | |
329 | else | |
330 | return (filterflags & COREFILTER_MAPPED_SHARED) != 0; | |
331 | } | |
332 | } | |
333 | ||
334 | /* List memory regions in the inferior PID matched to FILTERFLAGS for | |
335 | a corefile. Call FUNC with FUNC_DATA for each such region. Return | |
336 | immediately with the value returned by FUNC if it is non-zero. | |
337 | *MEMORY_TO_FREE_PTR should be registered to be freed automatically if | |
338 | called FUNC throws an exception. MEMORY_TO_FREE_PTR can be also | |
339 | passed as NULL if it is not used. Return -1 if error occurs, 0 if | |
340 | all memory regions have been processed or return the value from FUNC | |
341 | if FUNC returns non-zero. */ | |
342 | ||
343 | int | |
344 | linux_find_memory_regions_full (pid_t pid, enum filterflags filterflags, | |
345 | linux_find_memory_region_ftype *func, | |
346 | void *func_data) | |
347 | { | |
348 | char mapsfilename[100]; | |
349 | char *data; | |
350 | ||
351 | xsnprintf (mapsfilename, sizeof mapsfilename, "/proc/%d/smaps", pid); | |
352 | data = target_fileio_read_stralloc (NULL, mapsfilename); | |
353 | if (data == NULL) | |
354 | { | |
355 | /* Older Linux kernels did not support /proc/PID/smaps. */ | |
356 | xsnprintf (mapsfilename, sizeof mapsfilename, "/proc/%d/maps", pid); | |
357 | data = target_fileio_read_stralloc (NULL, mapsfilename); | |
358 | } | |
359 | ||
360 | if (data != NULL) | |
361 | { | |
362 | struct cleanup *cleanup = make_cleanup (xfree, data); | |
363 | char *line, *t; | |
364 | int retval = 0; | |
365 | ||
366 | line = strtok_r (data, "\n", &t); | |
367 | while (line != NULL) | |
368 | { | |
369 | ULONGEST addr, endaddr, offset, inode; | |
370 | const char *permissions, *device, *filename; | |
371 | struct smaps_vmflags v; | |
372 | size_t permissions_len, device_len; | |
373 | int read, write, exec, priv; | |
374 | int has_anonymous = 0; | |
375 | int should_dump_p = 0; | |
376 | int mapping_anon_p; | |
377 | int mapping_file_p; | |
378 | ||
379 | memset (&v, 0, sizeof (v)); | |
380 | read_mapping (line, &addr, &endaddr, &permissions, &permissions_len, | |
381 | &offset, &device, &device_len, &inode, &filename); | |
382 | mapping_anon_p = mapping_is_anonymous_p (filename); | |
383 | /* If the mapping is not anonymous, then we can consider it | |
384 | to be file-backed. These two states (anonymous or | |
385 | file-backed) seem to be exclusive, but they can actually | |
386 | coexist. For example, if a file-backed mapping has | |
387 | "Anonymous:" pages (see more below), then the Linux | |
388 | kernel will dump this mapping when the user specified | |
389 | that she only wants anonymous mappings in the corefile | |
390 | (*even* when she explicitly disabled the dumping of | |
391 | file-backed mappings). */ | |
392 | mapping_file_p = !mapping_anon_p; | |
393 | ||
394 | /* Decode permissions. */ | |
395 | read = (memchr (permissions, 'r', permissions_len) != 0); | |
396 | write = (memchr (permissions, 'w', permissions_len) != 0); | |
397 | exec = (memchr (permissions, 'x', permissions_len) != 0); | |
398 | /* 'private' here actually means VM_MAYSHARE, and not | |
399 | VM_SHARED. In order to know if a mapping is really | |
400 | private or not, we must check the flag "sh" in the | |
401 | VmFlags field. This is done by decode_vmflags. However, | |
402 | if we are using a Linux kernel released before the commit | |
403 | 834f82e2aa9a8ede94b17b656329f850c1471514 (3.10), we will | |
404 | not have the VmFlags there. In this case, there is | |
405 | really no way to know if we are dealing with VM_SHARED, | |
406 | so we just assume that VM_MAYSHARE is enough. */ | |
407 | priv = memchr (permissions, 'p', permissions_len) != 0; | |
408 | ||
409 | /* Try to detect if region should be dumped by parsing smaps | |
410 | counters. */ | |
411 | for (line = strtok_r (NULL, "\n", &t); | |
412 | line != NULL && line[0] >= 'A' && line[0] <= 'Z'; | |
413 | line = strtok_r (NULL, "\n", &t)) | |
414 | { | |
415 | char keyword[64 + 1]; | |
416 | ||
417 | if (sscanf (line, "%64s", keyword) != 1) | |
418 | { | |
419 | warning (_("Error parsing {s,}maps file '%s'"), mapsfilename); | |
420 | break; | |
421 | } | |
422 | ||
423 | if (strcmp (keyword, "Anonymous:") == 0) | |
424 | { | |
425 | /* Older Linux kernels did not support the | |
426 | "Anonymous:" counter. Check it here. */ | |
427 | has_anonymous = 1; | |
428 | } | |
429 | else if (strcmp (keyword, "VmFlags:") == 0) | |
430 | decode_vmflags (line, &v); | |
431 | ||
432 | if (strcmp (keyword, "AnonHugePages:") == 0 | |
433 | || strcmp (keyword, "Anonymous:") == 0) | |
434 | { | |
435 | unsigned long number; | |
436 | ||
437 | if (sscanf (line, "%*s%lu", &number) != 1) | |
438 | { | |
439 | warning (_("Error parsing {s,}maps file '%s' number"), | |
440 | mapsfilename); | |
441 | break; | |
442 | } | |
443 | if (number > 0) | |
444 | { | |
445 | /* Even if we are dealing with a file-backed | |
446 | mapping, if it contains anonymous pages we | |
447 | consider it to be *also* an anonymous | |
448 | mapping, because this is what the Linux | |
449 | kernel does: | |
450 | ||
451 | // Dump segments that have been written to. | |
452 | if (vma->anon_vma && FILTER(ANON_PRIVATE)) | |
453 | goto whole; | |
454 | ||
455 | Note that if the mapping is already marked as | |
456 | file-backed (i.e., mapping_file_p is | |
457 | non-zero), then this is a special case, and | |
458 | this mapping will be dumped either when the | |
459 | user wants to dump file-backed *or* anonymous | |
460 | mappings. */ | |
461 | mapping_anon_p = 1; | |
462 | } | |
463 | } | |
464 | } | |
465 | ||
466 | if (has_anonymous) | |
467 | should_dump_p = dump_mapping_p (filterflags, &v, priv, | |
468 | mapping_anon_p, mapping_file_p, | |
469 | filename); | |
470 | else | |
471 | { | |
472 | /* Older Linux kernels did not support the "Anonymous:" counter. | |
473 | If it is missing, we can't be sure - dump all the pages. */ | |
474 | should_dump_p = 1; | |
475 | } | |
476 | ||
477 | /* Invoke the callback function to create the corefile segment. */ | |
478 | if (should_dump_p) | |
479 | retval = func (addr, endaddr - addr, offset, inode, | |
480 | read, write, exec, | |
481 | 1, /* MODIFIED is true because we want to dump the | |
482 | mapping. */ | |
483 | filename, func_data); | |
484 | if (retval != 0) | |
485 | break; | |
486 | } | |
487 | ||
488 | do_cleanups (cleanup); | |
489 | return retval; | |
490 | } | |
491 | ||
492 | return -1; | |
493 | } |