sanitizer_procmaps_linux.cc 2.8 KB

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