123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522 |
- #include "shm_object.h"
- #include "shm_manager.h"
- #if defined(__GNUC__)
- #include <sys/types.h>
- #include <dirent.h>
- #define SHM_PATH "/dev/shm"
- namespace bg
- {
- namespace detail
- {
- bool GetDirectorySize(const char* path, size_t* const total_size)
- {
- bool result = false;
- char full_path[256]; // [rsp+A0h] [rbp-130h] BYREF
- DIR* path_dir = opendir(path);
- if(!path_dir)
- {
- return false;
- }
- struct dirent64* diren = readdir64(path_dir);
- if(!diren)
- {
- goto RETURN;
- }
- while(1)
- {
- snprintf(full_path, 0x100uLL, "%s/%s", path, diren->d_name);
- if(diren->d_type != DT_DIR) break;
- if(strcmp(diren->d_name, ".") && strcmp(diren->d_name, ".."))
- {
- st.st_dev = 0LL;
- if(!bg::detail::GetDirectorySize(full_path, &st.st_dev))
- {
- goto RETURN;
- }
- *total_size += st.st_dev;
- SHM_INFO("directory entry %s, size: %#lx", full_path, st.st_dev);
- }
- READ_DIR:
- diren = readdir64(path_dir);
- if(!diren)
- {
- result = 1;
- goto RETURN;
- }
- }
- if(diren->d_type != DT_REG)
- {
- SHM_WARN("entry %s, type: %u, ignored.", full_path, v4->d_type);
- goto READ_DIR;
- }
- if(!_lxstat64(1, full_path, (struct stat64*)&st))
- {
- *total_size += st.st_size;
- SHM_TRACE("file entry %s, size: %#lx", full_path, st.st_size);
- goto READ_DIR;
- }
- SHM_ERROR("lstat() failed, file: % s, error : % s.", full_path, strerror(_errno_location()));
- RETURN:
- closedir(v3);
- return false;
- }
- void* ShmObjectCreate(const char* path, uintptr_t fixed_addr, size_t* real_size, size_t* mmap_size)
- {
- size_t page_size = sysconf(_SC_PAGESIZE);
- int fd = shm_open(path, O_CREAT | O_RDWR, 0666);
- if(fd == -1)
- {
- int* error = _errno_location();
- v19 = v18;
- if(*error == 17)
- {
- SHM_INFO("shm object(%s) already exists, will be deleted.", path);
- if(shm_unlink(path))
- {
- SHM_ERROR("shm_unlink() failed, path: %s, error: %s.", path, strerror(*_errno_location()));
- SHM_ERROR
- }
- else
- {
- fd = shm_open(path, O_CREAT | O_RDWR, 0666);
- if(fd != -1) goto OPEN_SUCC;
- SHM_ERROR("shm_open() failed, path: %s, error: %s.", path, strerror(*_errno_location()));
- }
- }
- else
- {
- SHM_ERROR("shm_open() failed, path: %s, error: %s.", path, strerror(*_errno_location()))
- }
- return nullptr;
- }
- OPEN_SUCC:
- *real_size = PALIGN_UP(*real_size, page_size);
- size_t available_size;
- if(!bg::detail::GetAvailableMemorySize(available_size) || available_size < *real_size)
- {
- SHM_ERROR("shared memory not enough, available: %#lx, required: %#lx.", available_size, *real_size);
- close(fd);
- shm_unlink(path);
- return nullptr;
- }
- if(!ftruncate64(fd, *real_size))
- {
- int flag;
- if(*mmap_size < *real_size)
- {
- SHM_INFO("mmap size(%#lx) is not enough, revised to real size(%#lx).", *mmap_size, *real_size);
- *mmap_size = *real_size;
- }
- *mmap_size = PALIGN_UP(*mmap_size, page_size);
- if(fixed_addr)
- {
- if(fixed_addr & (page_size - 1))
- {
- uintptr_t new_addr = PALIGN_UP(fixed_addr, page_size);
- SHM_INFO("ixed address(%#lx) is not aligned to page size(%#lx), revised to %#lx.", fixed_addr, page_size, new_addr);
- fixed_addr = new_addr;
- }
- flag = MAP_SHARED;
- }
- else
- {
- flag = MAP_PRIVATE;
- }
- LABEL_13:
- char* mem = mmap64(fixed_addr, mmap_size, PROT_READ | PROT_WRITE, flag, fd, 0);
- if(mem != MAP_FAILED)
- {
- close(fd);
- return mem;
- }
- SHM_ERROR("mmap() failed, addr(% #lx), size(% #lx), error: % s.", old, *mmap_size), strerror(*_errno_location()));
- }
- else
- {
- SHM_ERROR("ftruncate() failed, path: % s, size : % #lx, error: % s.", path, *real_size, strerror(*_errno_location()));
- }
- close(v7);
- shm_unlink(path);
- return 0LL;
- }
- void* ShmObjectAttach(const char* path, uintptr_t fixed_addr, size_t* real_size, size_t* mmap_size)
- {
- size_t page_size = sysconf(_SC_PAGESIZE);
- int fd = shm_open(path, O_RDWR, 0666);
- if(fd != -1)
- {
- if(_fxstat64(1, fd, (struct stat64*)&st))
- {
- SHM_ERROR("fstat() failed, path: %s, error: %s.", path, strerror(*_errno_location()));
- LABEL_17:
- close(v9);
- return nullptr;
- }
- st_size = st.st_size;
- *real_size = st.st_size;
- if(st_size > *mmap_size)
- {
- SHM_INFO("mmap size(% #lx) is not enough, revised to real size(% #lx).", *mmap_size, st_size, *real_size);
- *mmap_size = *real_size;
- }
- *mmap_size = PALIGN_UP(*mmap_size, page_size);
- int flag;
- if(fixed_addr)
- {
- if(fixed_addr & (page_size - 1))
- {
- uintptr_t new_addr = PALIGN_UP(fixed_addr, page_size);
- SHM_INFO("fixed address(%#lx) is not aligned to page size(%#lx), revised to %#lx.", fixed_addr, page_size, new_addr);
- }
- flag = MAP_SHARED;
- }
- else
- {
- flag = MAP_PRIVATE;
- }
- LABEL_9:
- void* memory = mmap64(fixed_addr, *mmap_size, PROT_READ | PROT_WRITE, flag, fd, 0);
- if(v1memory5 != (void*)-1LL)
- {
- close(fd);
- return memory;
- }
- SHM_ERROR("mmap() failed, addr(%#lx), size(%#lx), error: %s.", memory, *mmap_size, strerror(*_errno_location()));
- close(fd);
- return nullptr;
- }
- SHM_ERROR("shm_open() failed, path: %s, error: %s.", path, strerror(*_errno_location()));
- close(fd);
- return nullptr;
- }
- void ShmObjectDelete(void* addr, uintptr_t mmap_size, const char* path)
- {
- if(munmap(addr, mmap_size))
- {
- strerror(*v5);
- SHM_ERROR("munmap() failed, addr(%p), mmap size(%#lx), error: %s.", addr, mmap_size, strerror(_errno_location()));
- }
- if(path)
- {
- if(shm_unlink(path))
- {
- v4 = _errno_location();
- strerror(*v4);
- SHM_ERROR("shm_unlink() failed, path: %s, error: %s.", path, strerror(_errno_location()));
- }
- }
- }
- bool ShmObjectResize(const char* path, size_t* new_size)
- {
- size_t available_size; // [rsp+8h] [rbp-B8h] BYREF
- size_t page_size = sysconf(_SC_PAGESIZE);
- int fd = shm_open(path, O_RDWR, 0666);
- if(fd != -1)
- {
- if(_fxstat64(1, fd, (struct stat64*)&st))
- {
- SHM_ERROR("fstat() failed, path: %s, error: %s.", path, strerror(*_errno_location()));
- }
- else
- {
- *new_size = PALIGN_UP(*new_size, page_size);
- st_size = st.st_size;
- if(st_size >= *new_size)
- {
- available_size = 0;
- if(bg::detail::GetAvailableMemorySize(&available_size))
- goto TRUNCAT;
- }
- else
- {
- available_size = 0;
- diff = *new_size - st_size;
- if(bg::detail::GetAvailableMemorySize(&available_size))
- {
- if(diff <= available_size)
- {
- TRUNCAT:
- if(!ftruncate64(fd, *new_size))
- {
- close(v4);
- return true;
- }
- SHM_ERROR("ftruncate() failed, path: %s, size: %#lx, error: %s.", path, *new_size, strerror(*_errno_location()));
- goto FAIL;
- }
- SHM_ERROR("shared memory not enough, available: %#lx, required: %#lx.", available_size, diff);
- }
- }
- }
- FAIL:
- close(v4);
- return false;
- }
- SHM_ERROR("shm_open() failed, path: % s, error : % s.", path, strerror(*_errno_location()));
- return false;
- }
- bool GetAvailableMemorySize(size_t* const size)
- {
- statvfs st; // [rsp+10h] [rbp-80h] BYREF
- if(statvfs64("/dev/shm", (struct statvfs64*)&st))
- {
- SHM_ERROR("statvfs() failed, path: %s, error: %s", SHM_PATH, strerror(*_errno_location()));
- return false;
- }
- else
- {
- size_t used_size = 0LL;
- bool ret = bg::detail::GetDirectorySize(SHM_PATH, &used_size);
- if(ret)
- {
- uintptr_t f_bsize = st.f_bsize;
- uintptr_t f_blocks = st.f_blocks;
- uintptr_t total_size = st.f_blocks * st.f_bsize;
- if(total_size < used_size)
- {
- return nullptr;
- }
- return total_size - used_size;
- }
- return ret;
- }
- }
- }
- }
- #else
- #include <windows.h>
- #include <Psapi.h>
- static std::unordered_map<std::string, HANDLE> g_mapping_handles;
- namespace bg
- {
- namespace detail
- {
- bool GetDirectorySize(const char* path, size_t* const total_size)
- {
- HANDLE handle = GetCurrentProcess();
- if(handle == nullptr)
- {
- return false;
- }
- PROCESS_MEMORY_COUNTERS pmc;
- GetProcessMemoryInfo(handle, &pmc, sizeof(pmc));
- *total_size = pmc.WorkingSetSize;
- return true;
- }
- void* ShmObjectCreate(const char* path, uintptr_t fixed_addr, size_t* real_size, size_t* mmap_size)
- {
- SYSTEM_INFO si;
- GetSystemInfo(&si);
- size_t pagesize = si.dwPageSize;
- size_t align = pagesize - 1;
- *real_size = PALIGN_UP(*real_size, pagesize);
- /*size_t available_size;
- if(!GetAvailableMemorySize(&available_size))
- {
- SHM_ASSERT(false && "ShmObjectCreate GetAvailableMemorySize FAIL");
- return nullptr;
- }
- if(*real_size > available_size)
- {
- SHM_ERROR("shared memory not enough, available: %#lx, required: %#lx.", available_size, *real_size);
- return nullptr;
- }*/
- HANDLE handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
- (uint32_t)(*real_size >> 32),
- (uint32_t)(*real_size & 0xffffffff),
- path);
- void* addr = nullptr;
- if(handle == nullptr)
- {
- SHM_ERROR("CreateFileMapping(%uz, %s) failed error:%s", *real_size, path, strerror(GetLastError()));
- return nullptr;
- }
- if(GetLastError() == ERROR_ALREADY_EXISTS)
- {
- SHM_WARN("shm object(%s) already exists, will be deleted.", path);
- if(CloseHandle(handle))
- {
- SHM_ERROR("CloseHandle failed, path: %s, error: %s.", path, strerror(GetLastError()));
- }
- handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
- (uint32_t)(*real_size >> 32),
- (uint32_t)(*real_size & 0xffffffff),
- path);
- if(handle == nullptr)
- {
- SHM_ERROR("CreateFileMapping failed, path: %s, error: %s.", strerror(GetLastError()));
- return nullptr;
- }
- if(GetLastError() != NO_ERROR)
- {
- goto END;
- }
- }
- if(*mmap_size != *real_size)
- {
- SHM_ERROR("mmap size(%#llx) is not enough, revised to real size(%#llx).", *mmap_size, *real_size);
- *mmap_size = *real_size;
- }
- *mmap_size = PALIGN_UP(*mmap_size, pagesize);
- if(fixed_addr)
- {
- uintptr_t base_addr = fixed_addr;
- if(base_addr & align)
- {
- base_addr = PALIGN_UP(fixed_addr, pagesize);
- SHM_WARN("fixed address(%#lx) is not aligned to page size(%#lx), revised to %#lx.", base_addr, pagesize, fixed_addr);
- fixed_addr = base_addr;
- }
- }
- addr = MapViewOfFileEx(handle, FILE_MAP_WRITE, 0, 0, *mmap_size, (void*)fixed_addr);
- if(addr == nullptr)
- {
- SHM_ERROR("CreateFileMapping failed, path: %s, error: %s.", path, strerror(GetLastError()));
- addr = MapViewOfFile(handle, FILE_MAP_WRITE, 0, 0, *mmap_size);
- }
- if(addr != nullptr)
- {
- g_mapping_handles[path] = handle;
- return addr;
- }
- END:
- SHM_ERROR("CreateFileMapping failed, path: %s, error: %s.", path, strerror(GetLastError()));
- CloseHandle(handle);
- return nullptr;
- }
- void* ShmObjectAttach(const char* path, uintptr_t fixed_addr, size_t* real_size, size_t* mmap_size)
- {
- SYSTEM_INFO si;
- GetSystemInfo(&si);
- size_t pagesize = si.dwPageSize;
- size_t align = pagesize - 1;
- HANDLE handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, path);
- void* addr = nullptr;
- if(handle == nullptr)
- {
- SHM_ERROR("OpenFileMapping(%uz, %s) failed error:%s", *real_size, path, strerror(GetLastError()));
- return nullptr;
- }
- if(*mmap_size < *real_size)
- {
- SHM_ERROR("mmap size(%#lx) is not enough, revised to real size(%#lx).", *mmap_size, *real_size);
- *mmap_size = *real_size;
- }
- *mmap_size = PALIGN_UP(*mmap_size, pagesize);
- if(fixed_addr)
- {
- uintptr_t base_addr = fixed_addr;
- if(base_addr & align)
- {
- base_addr = PALIGN_UP(fixed_addr, pagesize);
- SHM_WARN("fixed address(%#lx) is not aligned to page size(%#lx), revised to %#lx.", base_addr, pagesize, fixed_addr);
- fixed_addr = base_addr;
- }
- }
- addr = MapViewOfFileEx(handle, FILE_MAP_WRITE, 0, 0, *mmap_size, (void*)fixed_addr);
- if(addr == nullptr)
- {
- addr = MapViewOfFile(handle, FILE_MAP_WRITE, 0, 0, *mmap_size);
- }
- if(addr != nullptr)
- {
- g_mapping_handles[path] = handle;
- return addr;
- }
- SHM_ERROR("CreateFileMapping failed, path: %s, error: %s.", strerror(GetLastError()));
- CloseHandle(handle);
- return nullptr;
- }
- void ShmObjectDelete(void* addr, uintptr_t mmap_size, const char* path)
- {
- if(UnmapViewOfFile(addr) == 0)
- {
- SHM_ERROR("UnmapViewOfFile() failed, addr(%p), mmap size(%#lx), error: %s.", addr, mmap_size, strerror(GetLastError()));
- }
- auto itor = g_mapping_handles.find(path);
- if(itor == g_mapping_handles.end())
- {
- SHM_ASSERT(false);
- return;
- }
- CloseHandle(itor->second);
- g_mapping_handles.erase(itor);
- }
- bool ShmObjectResize(const char* path, size_t* new_size)
- {
- return false;
- }
- bool GetAvailableMemorySize(size_t* const size)
- {
- /*HANDLE handle = GetCurrentProcess();
- if(handle == nullptr)
- {
- return false;
- }
- PROCESS_MEMORY_COUNTERS pmc;
- GetProcessMemoryInfo(handle, &pmc, sizeof(pmc));
- *size = pmc.PeakWorkingSetSize - pmc.WorkingSetSize;
- return true;*/
- return false;
- }
- }
- }
- #endif
|