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 CHECK(ReadFileToBuffer("/proc/self/maps", &proc_maps->data, 22 &proc_maps->mmaped_size, &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(uptr *start, uptr *end, uptr *offset, 30 char filename[], uptr filename_size, 31 uptr *protection) { 32 char *last = proc_self_maps_.data + proc_self_maps_.len; 33 if (current_ >= last) return false; 34 uptr dummy; 35 if (!start) start = &dummy; 36 if (!end) end = &dummy; 37 if (!offset) offset = &dummy; 38 if (!protection) protection = &dummy; 39 char *next_line = (char*)internal_memchr(current_, '\n', last - current_); 40 if (next_line == 0) 41 next_line = last; 42 // Example: 08048000-08056000 r-xp 00000000 03:0c 64593 /foo/bar 43 *start = ParseHex(¤t_); 44 CHECK_EQ(*current_++, '-'); 45 *end = ParseHex(¤t_); 46 CHECK_EQ(*current_++, ' '); 47 CHECK(IsOneOf(*current_, '-', 'r')); 48 *protection = 0; 49 if (*current_++ == 'r') 50 *protection |= kProtectionRead; 51 CHECK(IsOneOf(*current_, '-', 'w')); 52 if (*current_++ == 'w') 53 *protection |= kProtectionWrite; 54 CHECK(IsOneOf(*current_, '-', 'x')); 55 if (*current_++ == 'x') 56 *protection |= kProtectionExecute; 57 CHECK(IsOneOf(*current_, 's', 'p')); 58 if (*current_++ == 's') 59 *protection |= kProtectionShared; 60 CHECK_EQ(*current_++, ' '); 61 *offset = ParseHex(¤t_); 62 CHECK_EQ(*current_++, ' '); 63 ParseHex(¤t_); 64 CHECK_EQ(*current_++, ':'); 65 ParseHex(¤t_); 66 CHECK_EQ(*current_++, ' '); 67 while (IsDecimal(*current_)) 68 current_++; 69 // Qemu may lack the trailing space. 70 // https://github.com/google/sanitizers/issues/160 71 // CHECK_EQ(*current_++, ' '); 72 // Skip spaces. 73 while (current_ < next_line && *current_ == ' ') 74 current_++; 75 // Fill in the filename. 76 uptr i = 0; 77 while (current_ < next_line) { 78 if (filename && i < filename_size - 1) 79 filename[i++] = *current_; 80 current_++; 81 } 82 if (filename && i < filename_size) 83 filename[i] = 0; 84 current_ = next_line + 1; 85 return true; 86 } 87 88 } // namespace __sanitizer 89 90 #endif // SANITIZER_LINUX 91