shm.cc 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include "shm.h"
  2. #include "shm_object.h"
  3. #include "shm_manager.h"
  4. bg::detail::ShmContext g_shm_ctx;
  5. namespace bg
  6. {
  7. ShmOptions::ShmOptions(bool resume, const char* identifier, ShmLogger* logger)
  8. {
  9. this->main_address = 0x600000000000LL;
  10. this->resume = resume;
  11. this->logger = logger;
  12. this->shm_block_mmap_size = 0x100000000LL;
  13. this->replace_sys_alloc = false;
  14. this->fix_vptr_on_init = 1;
  15. this->shm_block_grow_size = 0x2000000LL;
  16. snprintf(this->identifier, 64, "%s", identifier);
  17. this->fixed_address_count = bg::ShmOptions::FillDefaultFixedAddresses(this->fixed_addresses, 0x10uLL);
  18. }
  19. bool ShmOptions::AddFixedAddress(uintptr_t addr)
  20. {
  21. if(fixed_address_count <= 0)
  22. {
  23. fixed_address_count++;
  24. fixed_addresses[fixed_address_count] = addr;
  25. return true;
  26. }
  27. return false;
  28. }
  29. bool ShmOptions::PopFixedAddress(uintptr_t* addr)
  30. {
  31. if(fixed_address_count)
  32. {
  33. fixed_address_count--;
  34. if(addr)
  35. {
  36. *addr = fixed_addresses[fixed_address_count];
  37. return true;
  38. }
  39. return true;
  40. }
  41. return false;
  42. }
  43. size_t ShmOptions::FillDefaultFixedAddresses(uintptr_t* result, size_t max_count)
  44. {
  45. if(!max_count)
  46. {
  47. return max_count;
  48. }
  49. for(size_t i = 0; i < max_count; ++i)
  50. {
  51. result[i] = (126 - i) << 40;
  52. }
  53. return max_count;
  54. }
  55. bool ShmInit(const ShmOptions& options)
  56. {
  57. char path[256];
  58. bg::detail::ShmManager* manager;
  59. size_t total_bytes = sizeof(bg::detail::ShmManager);
  60. bool result;
  61. if(g_shm_ctx.mgr)
  62. {
  63. return true;
  64. }
  65. if(options.logger)
  66. {
  67. g_shm_ctx.logger = options.logger;
  68. }
  69. snprintf(path, 256, "%s-mgr.mmap", options.identifier);
  70. if(!options.resume)
  71. {
  72. manager = (bg::detail::ShmManager*)bg::detail::ShmObjectCreate(path, options.main_address, &total_bytes, &total_bytes);
  73. }
  74. else
  75. {
  76. manager = (bg::detail::ShmManager*)bg::detail::ShmObjectAttach(path, options.main_address, &total_bytes, &total_bytes);
  77. }
  78. if(manager)
  79. {
  80. if(options.resume || (new(manager) bg::detail::ShmManager(options), options.resume))
  81. {
  82. result = manager->OnResume(options.identifier);
  83. }
  84. else
  85. {
  86. result = manager->OnCreate();
  87. }
  88. if(!result)
  89. {
  90. manager->~ShmManager();
  91. bg::detail::ShmObjectDelete(manager, total_bytes, path);
  92. return false;
  93. }
  94. g_shm_ctx.mgr = manager;
  95. g_shm_ctx.mmap_size = total_bytes;
  96. snprintf(g_shm_ctx.path, 0x100uLL, "%s", path);
  97. if(!bg::detail::VptrManager::Init())
  98. {
  99. bg::ShmFini();
  100. return false;
  101. }
  102. if(!options.fix_vptr_on_init)
  103. {
  104. return true;
  105. }
  106. bg::detail::VptrManager::FixVptr();
  107. return true;
  108. }
  109. return false;
  110. }
  111. void ShmFini()
  112. {
  113. if(g_shm_ctx.mgr)
  114. {
  115. bg::detail::VptrManager::Fini();
  116. g_shm_ctx.mgr->~ShmManager();
  117. bg::detail::ShmObjectDelete(g_shm_ctx.mgr, g_shm_ctx.mmap_size, g_shm_ctx.path);
  118. g_shm_ctx.mgr = nullptr;
  119. g_shm_ctx.mmap_size = 0LL;
  120. memset(g_shm_ctx.path, 0, sizeof(g_shm_ctx.path));
  121. }
  122. }
  123. void ShmFixVptr()
  124. {
  125. bg::detail::VptrManager::FixVptr();
  126. }
  127. }