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