sanitizer_procmaps_solaris.cpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. //===-- sanitizer_procmaps_solaris.cpp ------------------------------------===//
  2. //
  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
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Information about the process mappings (Solaris-specific parts).
  10. //===----------------------------------------------------------------------===//
  11. // Before Solaris 11.4, <procfs.h> doesn't work in a largefile environment.
  12. #undef _FILE_OFFSET_BITS
  13. #include "sanitizer_platform.h"
  14. #if SANITIZER_SOLARIS
  15. #include "sanitizer_common.h"
  16. #include "sanitizer_procmaps.h"
  17. #include <procfs.h>
  18. #include <limits.h>
  19. namespace __sanitizer {
  20. void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {
  21. if (!ReadFileToBuffer("/proc/self/xmap", &proc_maps->data,
  22. &proc_maps->mmaped_size, &proc_maps->len)) {
  23. proc_maps->data = nullptr;
  24. proc_maps->mmaped_size = 0;
  25. proc_maps->len = 0;
  26. }
  27. }
  28. bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
  29. if (Error()) return false; // simulate empty maps
  30. char *last = data_.proc_self_maps.data + data_.proc_self_maps.len;
  31. if (data_.current >= last) return false;
  32. prxmap_t *xmapentry =
  33. const_cast<prxmap_t *>(reinterpret_cast<const prxmap_t *>(data_.current));
  34. segment->start = (uptr)xmapentry->pr_vaddr;
  35. segment->end = (uptr)(xmapentry->pr_vaddr + xmapentry->pr_size);
  36. segment->offset = (uptr)xmapentry->pr_offset;
  37. segment->protection = 0;
  38. if ((xmapentry->pr_mflags & MA_READ) != 0)
  39. segment->protection |= kProtectionRead;
  40. if ((xmapentry->pr_mflags & MA_WRITE) != 0)
  41. segment->protection |= kProtectionWrite;
  42. if ((xmapentry->pr_mflags & MA_EXEC) != 0)
  43. segment->protection |= kProtectionExecute;
  44. if (segment->filename != NULL && segment->filename_size > 0) {
  45. char proc_path[PATH_MAX + 1];
  46. internal_snprintf(proc_path, sizeof(proc_path), "/proc/self/path/%s",
  47. xmapentry->pr_mapname);
  48. ssize_t sz = internal_readlink(proc_path, segment->filename,
  49. segment->filename_size - 1);
  50. // If readlink failed, the map is anonymous.
  51. if (sz == -1) {
  52. segment->filename[0] = '\0';
  53. } else if ((size_t)sz < segment->filename_size)
  54. // readlink doesn't NUL-terminate.
  55. segment->filename[sz] = '\0';
  56. }
  57. data_.current += sizeof(prxmap_t);
  58. return true;
  59. }
  60. } // namespace __sanitizer
  61. #endif // SANITIZER_SOLARIS