]>
Commit | Line | Data |
---|---|---|
7d752f28 | 1 | //===-- sanitizer_procmaps_linux.cc ---------------------------------------===// |
2 | // | |
3 | // This file is distributed under the University of Illinois Open Source | |
4 | // License. See LICENSE.TXT for details. | |
5 | // | |
6 | //===----------------------------------------------------------------------===// | |
7 | // | |
8 | // Information about the process mappings (Linux-specific parts). | |
9 | //===----------------------------------------------------------------------===// | |
10 | ||
11 | #include "sanitizer_platform.h" | |
a9586c9c | 12 | #if SANITIZER_LINUX |
7d752f28 | 13 | #include "sanitizer_common.h" |
7d752f28 | 14 | #include "sanitizer_procmaps.h" |
15 | ||
7d752f28 | 16 | namespace __sanitizer { |
17 | ||
a9586c9c | 18 | void ReadProcMaps(ProcSelfMapsBuff *proc_maps) { |
d2ef4bee | 19 | if (!ReadFileToBuffer("/proc/self/maps", &proc_maps->data, |
20 | &proc_maps->mmaped_size, &proc_maps->len)) { | |
21 | proc_maps->data = nullptr; | |
22 | proc_maps->mmaped_size = 0; | |
23 | proc_maps->len = 0; | |
24 | } | |
7d752f28 | 25 | } |
26 | ||
27 | static bool IsOneOf(char c, char c1, char c2) { | |
28 | return c == c1 || c == c2; | |
29 | } | |
7d752f28 | 30 | |
36093749 | 31 | bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { |
32 | char *last = data_.proc_self_maps.data + data_.proc_self_maps.len; | |
33 | if (data_.current >= last) return false; | |
34 | char *next_line = | |
35 | (char *)internal_memchr(data_.current, '\n', last - data_.current); | |
7d752f28 | 36 | if (next_line == 0) |
37 | next_line = last; | |
38 | // Example: 08048000-08056000 r-xp 00000000 03:0c 64593 /foo/bar | |
36093749 | 39 | segment->start = ParseHex(&data_.current); |
40 | CHECK_EQ(*data_.current++, '-'); | |
41 | segment->end = ParseHex(&data_.current); | |
42 | CHECK_EQ(*data_.current++, ' '); | |
43 | CHECK(IsOneOf(*data_.current, '-', 'r')); | |
44 | segment->protection = 0; | |
45 | if (*data_.current++ == 'r') segment->protection |= kProtectionRead; | |
46 | CHECK(IsOneOf(*data_.current, '-', 'w')); | |
47 | if (*data_.current++ == 'w') segment->protection |= kProtectionWrite; | |
48 | CHECK(IsOneOf(*data_.current, '-', 'x')); | |
49 | if (*data_.current++ == 'x') segment->protection |= kProtectionExecute; | |
50 | CHECK(IsOneOf(*data_.current, 's', 'p')); | |
51 | if (*data_.current++ == 's') segment->protection |= kProtectionShared; | |
52 | CHECK_EQ(*data_.current++, ' '); | |
53 | segment->offset = ParseHex(&data_.current); | |
54 | CHECK_EQ(*data_.current++, ' '); | |
55 | ParseHex(&data_.current); | |
56 | CHECK_EQ(*data_.current++, ':'); | |
57 | ParseHex(&data_.current); | |
58 | CHECK_EQ(*data_.current++, ' '); | |
59 | while (IsDecimal(*data_.current)) data_.current++; | |
7d752f28 | 60 | // Qemu may lack the trailing space. |
23e39437 | 61 | // https://github.com/google/sanitizers/issues/160 |
36093749 | 62 | // CHECK_EQ(*data_.current++, ' '); |
7d752f28 | 63 | // Skip spaces. |
36093749 | 64 | while (data_.current < next_line && *data_.current == ' ') data_.current++; |
7d752f28 | 65 | // Fill in the filename. |
36093749 | 66 | if (segment->filename) { |
67 | uptr len = | |
68 | Min((uptr)(next_line - data_.current), segment->filename_size - 1); | |
69 | internal_strncpy(segment->filename, data_.current, len); | |
70 | segment->filename[len] = 0; | |
7d752f28 | 71 | } |
36093749 | 72 | |
73 | data_.current = next_line + 1; | |
7d752f28 | 74 | return true; |
75 | } | |
76 | ||
7d752f28 | 77 | } // namespace __sanitizer |
78 | ||
a9586c9c | 79 | #endif // SANITIZER_LINUX |