Misc.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include "Misc.hpp"
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include <signal.h>
  5. #include <setjmp.h>
  6. #include <errno.h>
  7. #include <unistd.h>
  8. #include <sys/stat.h>
  9. #include "ExceptionSystem.hpp"
  10. static jmp_buf g_jmbuf;
  11. static void SIGSEGV_handler(int sig) {
  12. siglongjmp(g_jmbuf, 1);
  13. }
  14. //
  15. // read byte(s) at address `p` as __Type to `out`
  16. // succeed if return true, otherwise return false
  17. //
  18. template<typename __Type>
  19. static inline bool probe_for_read(const void* p, void* out) {
  20. int r = sigsetjmp(g_jmbuf, 1);
  21. if (r == 0) {
  22. *reinterpret_cast<__Type*>(out) = *reinterpret_cast<const __Type*>(p);
  23. return true;
  24. } else {
  25. return false;
  26. }
  27. }
  28. namespace nkg::Misc {
  29. //
  30. // Print memory data in [lpMemBegin, lpMemEnd)
  31. // If `base` is not nullptr, print address as offset. Otherwise, as absolute address.
  32. // NOTICE:
  33. // `base` must >= `from`
  34. //
  35. void PrintMemory(const void* lpMemBegin, const void* lpMemEnd, const void* lpBase) noexcept {
  36. auto pbBegin = reinterpret_cast<const uint8_t*>(lpMemBegin);
  37. auto pbEnd = reinterpret_cast<const uint8_t*>(lpMemEnd);
  38. auto pbBase = reinterpret_cast<const uint8_t*>(lpBase);
  39. if (pbBegin >= pbEnd)
  40. return;
  41. while (reinterpret_cast<uintptr_t>(pbBegin) % 16)
  42. pbBegin--;
  43. while (reinterpret_cast<uintptr_t>(pbEnd) % 16)
  44. pbEnd++;
  45. while (pbBegin < pbEnd) {
  46. uint16_t Values[16] = {};
  47. if (pbBase) {
  48. uintptr_t d = pbBegin >= lpBase ? pbBegin - pbBase : pbBase - pbBegin;
  49. if (pbBegin >= lpBase) {
  50. printf("+0x%.*zx ", static_cast<int>(2 * sizeof(void*)), d);
  51. } else {
  52. printf("-0x%.*zx ", static_cast<int>(2 * sizeof(void*)), d);
  53. }
  54. } else {
  55. printf("0x%.*zx ", static_cast<int>(2 * sizeof(void*)), reinterpret_cast<uintptr_t>(pbBegin));
  56. }
  57. for (int i = 0; i < 16; ++i) {
  58. if (pbBegin + i < lpMemBegin || pbBegin + i >= lpMemEnd) {
  59. printf(" ");
  60. Values[i] = 0xfffe;
  61. } else if (probe_for_read<uint8_t>(pbBegin + i, Values + i)) {
  62. printf("%02x ", Values[i]);
  63. } else {
  64. printf("?? ");
  65. Values[i] = 0xffff;
  66. }
  67. }
  68. printf(" ");
  69. for (int i = 0; i < 16; ++i) {
  70. if (0x20 <= Values[i] && Values[i] < 0x7f) {
  71. printf("%c", Values[i]);
  72. } else if (Values[i] == 0xfffe) {
  73. printf(" ");
  74. } else {
  75. printf(".");
  76. }
  77. }
  78. printf("\n");
  79. pbBegin += 0x10;
  80. }
  81. }
  82. //
  83. // Print memory data in [lpMem, lpMem + cbMem)
  84. // If `base` is not nullptr, print address as offset. Otherwise, as absolute address.
  85. // NOTICE:
  86. // `base` must >= `from`
  87. //
  88. void PrintMemory(const void* lpMem, size_t cbMem, const void* lpBase) noexcept {
  89. PrintMemory(lpMem, reinterpret_cast<const uint8_t*>(lpMem) + cbMem, lpBase);
  90. }
  91. [[nodiscard]]
  92. bool FsIsExist(std::string_view szPath) {
  93. struct stat s = {};
  94. if (stat(szPath.data(), &s) == 0) {
  95. return true;
  96. } else {
  97. if (errno == ENOENT) {
  98. return false;
  99. } else {
  100. throw ARL::SystemError(__FILE__, __LINE__, errno, "stat failed.");
  101. }
  102. }
  103. }
  104. [[nodiscard]]
  105. bool FsIsFile(std::string_view szPath) {
  106. struct stat s = {};
  107. if (stat(szPath.data(), &s) == 0) {
  108. return S_ISREG(s.st_mode);
  109. } else {
  110. if (errno == ENOENT) {
  111. return false;
  112. } else {
  113. throw ARL::SystemError(__FILE__, __LINE__, errno, "stat failed.");
  114. }
  115. }
  116. }
  117. [[nodiscard]]
  118. bool FsIsDirectory(std::string_view szPath) {
  119. struct stat s = {};
  120. if (stat(szPath.data(), &s) == 0) {
  121. return S_ISDIR(s.st_mode);
  122. } else {
  123. if (errno == ENOENT) {
  124. return false;
  125. } else {
  126. throw ARL::SystemError(__FILE__, __LINE__, errno, "stat failed.");
  127. }
  128. }
  129. }
  130. [[nodiscard]]
  131. std::string FsCurrentWorkingDirectory() {
  132. std::string path(256, '\x00');
  133. while (getcwd(path.data(), path.size()) == 0) {
  134. if (errno == ERANGE) {
  135. path.resize(path.size() * 2);
  136. } else {
  137. throw ARL::SystemError(__FILE__, __LINE__, errno, "getcwd failed.");
  138. }
  139. }
  140. path.resize(strlen(path.data()));
  141. return path;
  142. }
  143. }