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" 12 #if SANITIZER_LINUX 13 #include "sanitizer_common.h" 14 #include "sanitizer_procmaps.h" 15 16 namespace __sanitizer { 17 18 void ReadProcMaps(ProcSelfMapsBuff *proc_maps) { 19 proc_maps->len = ReadFileToBuffer("/proc/self/maps", &proc_maps->data, 20 &proc_maps->mmaped_size, 1 << 26); 21 } 22 23 static bool IsOneOf(char c, char c1, char c2) { 24 return c == c1 || c == c2; 25 } 26 27 bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset, 28 char filename[], uptr filename_size, 29 uptr *protection) { 30 char *last = proc_self_maps_.data + proc_self_maps_.len; 31 if (current_ >= last) return false; 32 uptr dummy; 33 if (!start) start = &dummy; 34 if (!end) end = &dummy; 35 if (!offset) offset = &dummy; 36 if (!protection) protection = &dummy; 37 char *next_line = (char*)internal_memchr(current_, '\n', last - current_); 38 if (next_line == 0) 39 next_line = last; 40 // Example: 08048000-08056000 r-xp 00000000 03:0c 64593 /foo/bar 41 *start = ParseHex(¤t_); 42 CHECK_EQ(*current_++, '-'); 43 *end = ParseHex(¤t_); 44 CHECK_EQ(*current_++, ' '); 45 CHECK(IsOneOf(*current_, '-', 'r')); 46 *protection = 0; 47 if (*current_++ == 'r') 48 *protection |= kProtectionRead; 49 CHECK(IsOneOf(*current_, '-', 'w')); 50 if (*current_++ == 'w') 51 *protection |= kProtectionWrite; 52 CHECK(IsOneOf(*current_, '-', 'x')); 53 if (*current_++ == 'x') 54 *protection |= kProtectionExecute; 55 CHECK(IsOneOf(*current_, 's', 'p')); 56 if (*current_++ == 's') 57 *protection |= kProtectionShared; 58 CHECK_EQ(*current_++, ' '); 59 *offset = ParseHex(¤t_); 60 CHECK_EQ(*current_++, ' '); 61 ParseHex(¤t_); 62 CHECK_EQ(*current_++, ':'); 63 ParseHex(¤t_); 64 CHECK_EQ(*current_++, ' '); 65 while (IsDecimal(*current_)) 66 current_++; 67 // Qemu may lack the trailing space. 68 // http://code.google.com/p/address-sanitizer/issues/detail?id=160 69 // CHECK_EQ(*current_++, ' '); 70 // Skip spaces. 71 while (current_ < next_line && *current_ == ' ') 72 current_++; 73 // Fill in the filename. 74 uptr i = 0; 75 while (current_ < next_line) { 76 if (filename && i < filename_size - 1) 77 filename[i++] = *current_; 78 current_++; 79 } 80 if (filename && i < filename_size) 81 filename[i] = 0; 82 current_ = next_line + 1; 83 return true; 84 } 85 86 } // namespace __sanitizer 87 88 #endif // SANITIZER_LINUX 89