1 //===-- sanitizer_procmaps_linux.cpp --------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Information about the process mappings (Linux-specific parts).
10 //===----------------------------------------------------------------------===//
12 #include "sanitizer_platform.h"
14 #include "sanitizer_common.h"
15 #include "sanitizer_procmaps.h"
17 namespace __sanitizer
{
19 void ReadProcMaps(ProcSelfMapsBuff
*proc_maps
) {
20 if (!ReadFileToBuffer("/proc/self/maps", &proc_maps
->data
,
21 &proc_maps
->mmaped_size
, &proc_maps
->len
)) {
22 proc_maps
->data
= nullptr;
23 proc_maps
->mmaped_size
= 0;
28 static bool IsOneOf(char c
, char c1
, char c2
) {
29 return c
== c1
|| c
== c2
;
32 bool MemoryMappingLayout::Next(MemoryMappedSegment
*segment
) {
33 if (Error()) return false; // simulate empty maps
34 char *last
= data_
.proc_self_maps
.data
+ data_
.proc_self_maps
.len
;
35 if (data_
.current
>= last
) return false;
37 (char *)internal_memchr(data_
.current
, '\n', last
- data_
.current
);
40 // Example: 08048000-08056000 r-xp 00000000 03:0c 64593 /foo/bar
41 segment
->start
= ParseHex(&data_
.current
);
42 CHECK_EQ(*data_
.current
++, '-');
43 segment
->end
= ParseHex(&data_
.current
);
44 CHECK_EQ(*data_
.current
++, ' ');
45 CHECK(IsOneOf(*data_
.current
, '-', 'r'));
46 segment
->protection
= 0;
47 if (*data_
.current
++ == 'r') segment
->protection
|= kProtectionRead
;
48 CHECK(IsOneOf(*data_
.current
, '-', 'w'));
49 if (*data_
.current
++ == 'w') segment
->protection
|= kProtectionWrite
;
50 CHECK(IsOneOf(*data_
.current
, '-', 'x'));
51 if (*data_
.current
++ == 'x') segment
->protection
|= kProtectionExecute
;
52 CHECK(IsOneOf(*data_
.current
, 's', 'p'));
53 if (*data_
.current
++ == 's') segment
->protection
|= kProtectionShared
;
54 CHECK_EQ(*data_
.current
++, ' ');
55 segment
->offset
= ParseHex(&data_
.current
);
56 CHECK_EQ(*data_
.current
++, ' ');
57 ParseHex(&data_
.current
);
58 CHECK_EQ(*data_
.current
++, ':');
59 ParseHex(&data_
.current
);
60 CHECK_EQ(*data_
.current
++, ' ');
61 while (IsDecimal(*data_
.current
)) data_
.current
++;
62 // Qemu may lack the trailing space.
63 // https://github.com/google/sanitizers/issues/160
64 // CHECK_EQ(*data_.current++, ' ');
66 while (data_
.current
< next_line
&& *data_
.current
== ' ') data_
.current
++;
67 // Fill in the filename.
68 if (segment
->filename
) {
70 Min((uptr
)(next_line
- data_
.current
), segment
->filename_size
- 1);
71 internal_strncpy(segment
->filename
, data_
.current
, len
);
72 segment
->filename
[len
] = 0;
75 data_
.current
= next_line
+ 1;
79 } // namespace __sanitizer
81 #endif // SANITIZER_LINUX