diff --git a/bundle.json b/bundle.json index 25c4c150d1294f2317938f61edde7dc808774ae9..7b5b9300f50d14b6234c3db20c14493cc8423670 100644 --- a/bundle.json +++ b/bundle.json @@ -26,7 +26,8 @@ "build": { "sub_component": [ "//commonlibrary/memory_utils/libdmabufheap:libdmabufheap", - "//commonlibrary/memory_utils/libpurgeablemem:libpurgeablemem" + "//commonlibrary/memory_utils/libpurgeablemem:libpurgeablemem", + "//commonlibrary/memory_utils/libpurgeablemem:purgeable_memory_ndk" ], "inner_kits": [ { diff --git a/libpurgeablemem/BUILD.gn b/libpurgeablemem/BUILD.gn index bec592f0c1d9a027474e1ed8052813e07031b512..eea8e5449b584ac9bf503fbe5aa60b6eb5174d70 100644 --- a/libpurgeablemem/BUILD.gn +++ b/libpurgeablemem/BUILD.gn @@ -12,12 +12,14 @@ # limitations under the License. import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") config("libpurgeable_config") { include_dirs = [ "c/include", "common/include", "cpp/include", + "interfaces/kits/c", ] cflags_cc = [ "-fexceptions" ] } @@ -26,6 +28,7 @@ ohos_shared_library("libpurgeablemem") { sources = [ "c/src/purgeable_mem_builder_c.c", "c/src/purgeable_mem_c.c", + "c/src/purgeable_memory.c", "common/src/pm_state_c.c", "common/src/ux_page_table_c.c", "cpp/src/purgeable_ashmem.cpp", @@ -43,3 +46,18 @@ ohos_shared_library("libpurgeablemem") { subsystem_name = "commonlibrary" part_name = "memory_utils" } + +ohos_shared_library("purgeable_memory_ndk") { + include_dirs = [ "interfaces/kits/c" ] + + sources = [ "c/src/purgeable_memory.c" ] + deps = [ ":libpurgeablemem" ] + external_deps = [ + "c_utils:utils", + "hiviewdfx_hilog_native:libhilog", + ] + + relative_install_dir = "ndk" + subsystem_name = "commonlibrary" + part_name = "memory_utils" +} diff --git a/libpurgeablemem/c/include/pm_log_c.h b/libpurgeablemem/c/include/pm_log_c.h new file mode 100644 index 0000000000000000000000000000000000000000..f581b6ab96d0849622122c6ad52e948a8e9ac14c --- /dev/null +++ b/libpurgeablemem/c/include/pm_log_c.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_UTILS_MEMORY_LIBPURGEABLEMEM_CPP_INCLUDE_PM_LOG_C_H +#define OHOS_UTILS_MEMORY_LIBPURGEABLEMEM_CPP_INCLUDE_PM_LOG_C_H + +#include "hilog/log.h" + +#undef LOG_DOMAIN +#undef LOG_TAG +#define LOG_DOMAIN 0xD001799 + +#ifdef PM_HILOG_ERROR_C +#undef PM_HILOG_ERROR_C +#endif + +#ifdef PM_HILOG_INFO_C +#undef PM_HILOG_INFO_C +#endif + +#ifdef PM_HILOG_DEBUG_C +#undef PM_HILOG_DEBUG_C +#endif + +#define PM_FILENAME "purgeable" + +#define PM_HILOG_ERROR_C(logCore, fmt, ...) \ + (void)HILOG_ERROR( \ + LOG_CORE, "[%{public}s(%{public}s:%{public}d)]" fmt, PM_FILENAME, __FUNCTION__, __LINE__, ##__VA_ARGS__) + +#define PM_HILOG_INFO_C(logCore, fmt, ...) \ + (void)HILOG_INFO( \ + LOG_CORE, "[%{public}s(%{public}s:%{public}d)]" fmt, PM_FILENAME, __FUNCTION__, __LINE__, ##__VA_ARGS__) + +#define PM_HILOG_DEBUG_C(logCore, fmt, ...) \ + (void)HILOG_DEBUG( \ + LOG_CORE, "[%{public}s(%{public}s:%{public}d)]" fmt, PM_FILENAME, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#endif \ No newline at end of file diff --git a/libpurgeablemem/c/src/purgeable_mem_builder_c.c b/libpurgeablemem/c/src/purgeable_mem_builder_c.c index 43e288cc58581f7083d365d3e3d259ab986460a8..20023add30b81f189150f1727860156ed62f3b7d 100644 --- a/libpurgeablemem/c/src/purgeable_mem_builder_c.c +++ b/libpurgeablemem/c/src/purgeable_mem_builder_c.c @@ -19,6 +19,7 @@ #include "hilog/log_c.h" #include "pm_ptr_util.h" +#include "pm_log_c.h" #include "purgeable_mem_builder_c.h" #undef LOG_TAG @@ -42,7 +43,7 @@ struct PurgMemBuilder *PurgMemBuilderCreate(PurgMemBuilderFunc func, void *param struct PurgMemBuilder *builder = NULL; builder = (struct PurgMemBuilder *)malloc(sizeof(struct PurgMemBuilder)); if (!builder) { - HILOG_ERROR(LOG_CORE, "%{public}s: malloc struct PurgMemBuilder failed", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: malloc struct PurgMemBuilder failed", __func__); return NULL; } builder->Build = func; @@ -85,11 +86,11 @@ bool PurgMemBuilderAppendFunc(struct PurgMemBuilder *builder, PurgMemBuilderFunc bool PurgMemBuilderBuildAll(struct PurgMemBuilder *builder, void *data, size_t size) { if (!(builder->Build)) { - HILOG_ERROR(LOG_CORE, "builder has no Build(), %{public}s", builder->name); + PM_HILOG_ERROR_C(LOG_CORE, "builder has no Build(), %{public}s", builder->name); return true; } if (!(builder->Build(data, size, builder->param))) { - HILOG_ERROR(LOG_CORE, "build data failed, name %{public}s", builder->name ?: "NULL"); + PM_HILOG_ERROR_C(LOG_CORE, "build data failed, name %{public}s", builder->name ?: "NULL"); return false; } if (!(builder->nextBuilder)) { diff --git a/libpurgeablemem/c/src/purgeable_mem_c.c b/libpurgeablemem/c/src/purgeable_mem_c.c index eb0c846d17f6b65f27192f026d6666d7d8938a7c..3e36bb654d9294850bc720287745d059dcde572e 100644 --- a/libpurgeablemem/c/src/purgeable_mem_c.c +++ b/libpurgeablemem/c/src/purgeable_mem_c.c @@ -24,6 +24,7 @@ #include "pm_state_c.h" #include "ux_page_table_c.h" #include "purgeable_mem_builder_c.h" +#include "pm_log_c.h" #include "purgeable_mem_c.h" #undef LOG_TAG @@ -40,7 +41,7 @@ struct PurgMem { static inline void LogPurgMemInfo_(struct PurgMem *obj) { - HILOG_INFO(LOG_CORE, "purgMemObj(%{public}lx) dataPtr(%{public}lx) dataSizeInput(%{public}zu)" + PM_HILOG_INFO_C(LOG_CORE, "purgMemObj(%{public}lx) dataPtr(%{public}lx) dataSizeInput(%{public}zu)" " builderPtr(%{public}lx) uxpt(%{public}lx)", (unsigned long)obj, (unsigned long)(obj->dataPtr), obj->dataSizeInput, (unsigned long)(obj->builder), (unsigned long)(obj->uxPageTable)); @@ -63,7 +64,7 @@ static struct PurgMem *PurgMemCreate_(size_t len, struct PurgMemBuilder *builder struct PurgMem *pugObj = NULL; pugObj = (struct PurgMem *)malloc(sizeof(struct PurgMem)); if (!pugObj) { - HILOG_ERROR(LOG_CORE, "%{public}s: malloc struct PurgMem fail", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: malloc struct PurgMem fail", __func__); return NULL; } size_t size = RoundUp_(len, PAGE_SIZE); @@ -71,31 +72,32 @@ static struct PurgMem *PurgMemCreate_(size_t len, struct PurgMemBuilder *builder type |= (UxpteIsEnabled() ? MAP_PURGEABLE : MAP_PRIVATE); pugObj->dataPtr = mmap(NULL, size, PROT_READ | PROT_WRITE, type, -1, 0); if (pugObj->dataPtr == MAP_FAILED) { - HILOG_ERROR(LOG_CORE, "%{public}s: mmap dataPtr fail", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: mmap dataPtr fail", __func__); pugObj->dataPtr = NULL; goto free_pug_obj; } pugObj->uxPageTable = (UxPageTableStruct *)malloc(UxPageTableSize()); if (!(pugObj->uxPageTable)) { - HILOG_ERROR(LOG_CORE, "%{public}s: malloc UxPageTableStruct fail", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: malloc UxPageTableStruct fail", __func__); goto unmap_data; } PMState err = InitUxPageTable(pugObj->uxPageTable, (uint64_t)(pugObj->dataPtr), size); /* dataPtr is aligned */ if (err != PM_OK) { - HILOG_ERROR(LOG_CORE, "%{public}s: InitUxPageTable fail, %{public}s", __func__, GetPMStateName(err)); + PM_HILOG_ERROR_C(LOG_CORE, + "%{public}s: InitUxPageTable fail, %{public}s", __func__, GetPMStateName(err)); goto free_uxpt; } int lockInitRet = pthread_rwlock_init(&(pugObj->rwlock), NULL); if (lockInitRet != 0) { - HILOG_ERROR(LOG_CORE, "%{public}s: pthread_rwlock_init fail, %{public}d", __func__, lockInitRet); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: pthread_rwlock_init fail, %{public}d", __func__, lockInitRet); goto deinit_upt; } pugObj->builder = builder; pugObj->dataSizeInput = len; pugObj->buildDataCount = 0; - HILOG_INFO(LOG_CORE, "%{public}s: LogPurgMemInfo_:", __func__); + PM_HILOG_INFO_C(LOG_CORE, "%{public}s: LogPurgMemInfo_:", __func__); LogPurgMemInfo_(pugObj); return pugObj; @@ -117,7 +119,7 @@ free_pug_obj: struct PurgMem *PurgMemCreate(size_t len, PurgMemModifyFunc func, void *funcPara) { if (len == 0) { - HILOG_ERROR(LOG_CORE, "%{public}s: input len 0", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: input len 0", __func__); return NULL; } /* a PurgMemObj must have builder */ @@ -133,9 +135,9 @@ struct PurgMem *PurgMemCreate(size_t len, PurgMemModifyFunc func, void *funcPara } /* append func fail meas create builder failed */ - HILOG_ERROR(LOG_CORE, "%{public}s: append mod func fail", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: append mod func fail", __func__); if (!PurgMemDestroy(purgMemObj)) { - HILOG_ERROR(LOG_CORE, "%{public}s: destroy PurgMem fail after append modFunc fail", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: destroy PurgMem fail after append modFunc fail", __func__); } return NULL; } @@ -143,19 +145,19 @@ struct PurgMem *PurgMemCreate(size_t len, PurgMemModifyFunc func, void *funcPara bool PurgMemDestroy(struct PurgMem *purgObj) { IF_NULL_LOG_ACTION(purgObj, "input is NULL", return true); - HILOG_INFO(LOG_CORE, "%{public}s: LogPurgMemInfo_:", __func__); + PM_HILOG_INFO_C(LOG_CORE, "%{public}s: LogPurgMemInfo_:", __func__); LogPurgMemInfo_(purgObj); PMState err = PM_OK; /* destroy rwlock */ int ret = pthread_rwlock_destroy(&(purgObj->rwlock)); if (ret != 0) { - HILOG_ERROR(LOG_CORE, "%{public}s: pthread_rwlock_destroy fail, %{public}d", __func__, ret); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: pthread_rwlock_destroy fail, %{public}d", __func__, ret); } /* destroy builder */ if (purgObj->builder) { if (!PurgMemBuilderDestroy(purgObj->builder)) { - HILOG_ERROR(LOG_CORE, "%{public}s: PurgMemBuilderDestroy fail", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: PurgMemBuilderDestroy fail", __func__); err = PMB_DESTORY_FAIL; } else { purgObj->builder = NULL; @@ -165,12 +167,12 @@ bool PurgMemDestroy(struct PurgMem *purgObj) if (purgObj->dataPtr) { size_t size = RoundUp_(purgObj->dataSizeInput, PAGE_SIZE); if (munmap(purgObj->dataPtr, size) != 0) { - HILOG_ERROR(LOG_CORE, "%{public}s: munmap dataPtr fail", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: munmap dataPtr fail", __func__); err = PM_UNMAP_PURG_FAIL; } else { /* double check munmap result: if uxpte is set to no_present */ if (UxpteIsEnabled() && !IsPurged_(purgObj)) { - HILOG_ERROR(LOG_CORE, "%{public}s: munmap dataPtr succ, but uxpte present", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: munmap dataPtr succ, but uxpte present", __func__); err = PM_UXPT_PRESENT_DATA_PURGED; } purgObj->dataPtr = NULL; @@ -180,7 +182,8 @@ bool PurgMemDestroy(struct PurgMem *purgObj) if (purgObj->uxPageTable) { PMState deinitRet = DeinitUxPageTable(purgObj->uxPageTable); if (deinitRet != PM_OK) { - HILOG_ERROR(LOG_CORE, "%{public}s: deinit upt fail, %{public}s", __func__, GetPMStateName(deinitRet)); + PM_HILOG_ERROR_C(LOG_CORE, + "%{public}s: deinit upt fail, %{public}s", __func__, GetPMStateName(deinitRet)); err = deinitRet; } else { free(purgObj->uxPageTable); @@ -191,10 +194,10 @@ bool PurgMemDestroy(struct PurgMem *purgObj) if (err == PM_OK) { free(purgObj); purgObj = NULL; /* set input para NULL to avoid UAF */ - HILOG_ERROR(LOG_CORE, "%{public}s: succ", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: succ", __func__); return true; } - HILOG_ERROR(LOG_CORE, "%{public}s: fail, %{public}s", __func__, GetPMStateName(err)); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: fail, %{public}s", __func__, GetPMStateName(err)); return false; } @@ -213,7 +216,7 @@ static inline bool PurgMemBuildData_(struct PurgMem *purgObj) bool succ = false; /* clear content before rebuild */ if (memset_s(purgObj->dataPtr, RoundUp_(purgObj->dataSizeInput, PAGE_SIZE), 0, purgObj->dataSizeInput) != EOK) { - HILOG_ERROR(LOG_CORE, "%{public}s, clear content fail", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s, clear content fail", __func__); return succ; } /* @purgObj->builder is not NULL since it is checked by IsPurgMemPtrValid_() before */ @@ -228,18 +231,19 @@ static PMState TryBeginRead_(struct PurgMem *purgObj) { int rwlockRet = pthread_rwlock_rdlock(&(purgObj->rwlock)); if (rwlockRet != 0) { - HILOG_ERROR(LOG_CORE, "%{public}s: rdlock fail. %{public}d", __func__, rwlockRet); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: rdlock fail. %{public}d", __func__, rwlockRet); return PM_LOCK_READ_FAIL; } if (!IsPurged_(purgObj)) { - HILOG_INFO(LOG_CORE, "%{public}s: not purged, return true. MAP_PUG=0x%{public}x", __func__, MAP_PURGEABLE); + PM_HILOG_INFO_C(LOG_CORE, + "%{public}s: not purged, return true. MAP_PUG=0x%{public}x", __func__, MAP_PURGEABLE); return PM_DATA_NO_PURGED; } rwlockRet = pthread_rwlock_unlock(&(purgObj->rwlock)); if (rwlockRet != 0) { - HILOG_ERROR(LOG_CORE, "%{public}s: rd unlock fail. %{public}d", __func__, rwlockRet); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: rd unlock fail. %{public}d", __func__, rwlockRet); return PM_UNLOCK_READ_FAIL; } @@ -251,18 +255,19 @@ static PMState BeginReadBuildData_(struct PurgMem *purgObj) bool rebuildRet = false; int rwlockRet = pthread_rwlock_wrlock(&(purgObj->rwlock)); if (rwlockRet) { - HILOG_ERROR(LOG_CORE, "%{public}s: wrlock fail. %{public}d", __func__, rwlockRet); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: wrlock fail. %{public}d", __func__, rwlockRet); return PM_LOCK_WRITE_FAIL; } if (IsPurged_(purgObj)) { rebuildRet = PurgMemBuildData_(purgObj); - HILOG_ERROR(LOG_CORE, "%{public}s: purged, after built %{public}s", __func__, rebuildRet ? "succ" : "fail"); + PM_HILOG_ERROR_C(LOG_CORE, + "%{public}s: purged, after built %{public}s", __func__, rebuildRet ? "succ" : "fail"); } rwlockRet = pthread_rwlock_unlock(&(purgObj->rwlock)); if (rwlockRet != 0) { - HILOG_ERROR(LOG_CORE, "%{public}s: wr unlock fail. %{public}d", __func__, rwlockRet); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: wr unlock fail. %{public}d", __func__, rwlockRet); return PM_UNLOCK_WRITE_FAIL; } @@ -276,10 +281,10 @@ static PMState BeginReadBuildData_(struct PurgMem *purgObj) bool PurgMemBeginRead(struct PurgMem *purgObj) { if (!IsPurgMemPtrValid_(purgObj)) { - HILOG_ERROR(LOG_CORE, "%{public}s: para is invalid", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: para is invalid", __func__); return false; } - HILOG_INFO(LOG_CORE, "%{public}s: LogPurgMemInfo_:", __func__); + PM_HILOG_INFO_C(LOG_CORE, "%{public}s: LogPurgMemInfo_:", __func__); LogPurgMemInfo_(purgObj); bool ret = false; PMState err = PM_OK; @@ -301,7 +306,7 @@ bool PurgMemBeginRead(struct PurgMem *purgObj) } if (!ret) { - HILOG_ERROR(LOG_CORE, "%{public}s: %{public}s, UxptePut.", __func__, GetPMStateName(err)); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: %{public}s, UxptePut.", __func__, GetPMStateName(err)); UxptePut(purgObj->uxPageTable, (uint64_t)(purgObj->dataPtr), purgObj->dataSizeInput); } return ret; @@ -310,10 +315,10 @@ bool PurgMemBeginRead(struct PurgMem *purgObj) bool PurgMemBeginWrite(struct PurgMem *purgObj) { if (!IsPurgMemPtrValid_(purgObj)) { - HILOG_ERROR(LOG_CORE, "%{public}s: para is invalid", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: para is invalid", __func__); return false; } - HILOG_INFO(LOG_CORE, "%{public}s: LogPurgMemInfo_:", __func__); + PM_HILOG_INFO_C(LOG_CORE, "%{public}s: LogPurgMemInfo_:", __func__); LogPurgMemInfo_(purgObj); int rwlockRet = 0; bool rebuildRet = false; @@ -323,7 +328,7 @@ bool PurgMemBeginWrite(struct PurgMem *purgObj) rwlockRet = pthread_rwlock_wrlock(&(purgObj->rwlock)); if (rwlockRet != 0) { - HILOG_ERROR(LOG_CORE, "%{public}s: wrlock fail. %{public}d", __func__, rwlockRet); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: wrlock fail. %{public}d", __func__, rwlockRet); err = PM_LOCK_WRITE_FAIL; goto uxpte_put; } @@ -334,7 +339,7 @@ bool PurgMemBeginWrite(struct PurgMem *purgObj) /* data is purged */ rebuildRet = PurgMemBuildData_(purgObj); - HILOG_INFO(LOG_CORE, "%{public}s: purged, built %{public}s", __func__, rebuildRet ? "succ" : "fail"); + PM_HILOG_INFO_C(LOG_CORE, "%{public}s: purged, built %{public}s", __func__, rebuildRet ? "succ" : "fail"); if (rebuildRet) { goto succ; } @@ -342,11 +347,11 @@ bool PurgMemBeginWrite(struct PurgMem *purgObj) err = PMB_BUILD_ALL_FAIL; rwlockRet = pthread_rwlock_unlock(&(purgObj->rwlock)); if (rwlockRet != 0) { - HILOG_ERROR(LOG_CORE, "%{public}s: wr unlock fail. %{public}d", __func__, rwlockRet); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: wr unlock fail. %{public}d", __func__, rwlockRet); } uxpte_put: - HILOG_ERROR(LOG_CORE, "%{public}s: %{public}s, return false, UxptePut.", __func__, GetPMStateName(err)); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: %{public}s, return false, UxptePut.", __func__, GetPMStateName(err)); UxptePut(purgObj->uxPageTable, (uint64_t)(purgObj->dataPtr), purgObj->dataSizeInput); return false; succ: @@ -356,13 +361,13 @@ succ: static inline void EndAccessPurgMem_(struct PurgMem *purgObj) { if (!IsPurgMemPtrValid_(purgObj)) { - HILOG_ERROR(LOG_CORE, "%{public}s: para is invalid", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: para is invalid", __func__); return; } int rwlockRet = 0; rwlockRet = pthread_rwlock_unlock(&(purgObj->rwlock)); if (rwlockRet != 0) { - HILOG_ERROR(LOG_CORE, "%{public}s: unlock fail. %{public}d", __func__, rwlockRet); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: unlock fail. %{public}d", __func__, rwlockRet); } UxptePut(purgObj->uxPageTable, (uint64_t)(purgObj->dataPtr), purgObj->dataSizeInput); } @@ -380,7 +385,7 @@ void PurgMemEndWrite(struct PurgMem *purgObj) void *PurgMemGetContent(struct PurgMem *purgObj) { if (!IsPurgMemPtrValid_(purgObj)) { - HILOG_ERROR(LOG_CORE, "%{public}s: para is invalid", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: para is invalid", __func__); return NULL; } return purgObj->dataPtr; @@ -389,7 +394,7 @@ void *PurgMemGetContent(struct PurgMem *purgObj) size_t PurgMemGetContentSize(struct PurgMem *purgObj) { if (!IsPurgMemPtrValid_(purgObj)) { - HILOG_ERROR(LOG_CORE, "%{public}s: para is invalid", __func__); + PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: para is invalid", __func__); return 0; } return purgObj->dataSizeInput; @@ -418,7 +423,7 @@ static bool IsPurged_(struct PurgMem *purgObj) { /* first access, return true means purged */ if (purgObj->buildDataCount == 0) { - HILOG_INFO(LOG_CORE, "%{public}s, has never built, return true", __func__); + PM_HILOG_INFO_C(LOG_CORE, "%{public}s, has never built, return true", __func__); return true; } return !UxpteIsPresent(purgObj->uxPageTable, (uint64_t)(purgObj->dataPtr), purgObj->dataSizeInput); diff --git a/libpurgeablemem/c/src/purgeable_memory.c b/libpurgeablemem/c/src/purgeable_memory.c new file mode 100644 index 0000000000000000000000000000000000000000..4290dcaddadc556fcaec846dd221075050be5ae3 --- /dev/null +++ b/libpurgeablemem/c/src/purgeable_memory.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "pthread.h" + +#include "purgeable_mem_builder_c.h" +#include "purgeable_mem_c.h" +#include "ux_page_table_c.h" +#include "purgeable_memory.h" + +#undef LOG_TAG +#define LOG_TAG "PurgeableMemNDK" + +typedef bool (*OH_PurgeableMemory_ModifyFunc)(void *, size_t, void *); +typedef struct PurgMem OH_PurgeableMemory; +typedef struct PurgMem PurgMem; + +OH_PurgeableMemory *OH_PurgeableMemory_Create( + size_t size, OH_PurgeableMemory_ModifyFunc func, void *funcPara) +{ + return (OH_PurgeableMemory *)PurgMemCreate(size, func, funcPara); +} + +bool OH_PurgeableMemory_Destroy(OH_PurgeableMemory *purgObj) +{ + return PurgMemDestroy((PurgMem *)purgObj); +} + +bool OH_PurgeableMemory_BeginRead(OH_PurgeableMemory *purgObj) +{ + return PurgMemBeginRead((PurgMem *)purgObj); +} + +void OH_PurgeableMemory_EndRead(OH_PurgeableMemory *purgObj) +{ + PurgMemEndRead((PurgMem *)purgObj); +} + +bool OH_PurgeableMemory_BeginWrite(OH_PurgeableMemory *purgObj) +{ + return PurgMemBeginWrite((PurgMem *)purgObj); +} + +void OH_PurgeableMemory_EndWrite(OH_PurgeableMemory *purgObj) +{ + PurgMemEndWrite((PurgMem *)purgObj); +} + +void *OH_PurgeableMemory_GetContent(OH_PurgeableMemory *purgObj) +{ + return PurgMemGetContent((PurgMem *)purgObj); +} + +size_t OH_PurgeableMemory_ContentSize(OH_PurgeableMemory *purgObj) +{ + return PurgMemGetContentSize((PurgMem *)purgObj); +} + +bool OH_PurgeableMemory_AppendModify(OH_PurgeableMemory *purgObj, + OH_PurgeableMemory_ModifyFunc func, void *funcPara) +{ + return PurgMemAppendModify((PurgMem *)purgObj, func, funcPara); +} \ No newline at end of file diff --git a/libpurgeablemem/interfaces/kits/c/BUILD.gn b/libpurgeablemem/interfaces/kits/c/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..a2ae01d826babb6df89bf3e270d9abab17755400 --- /dev/null +++ b/libpurgeablemem/interfaces/kits/c/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (C) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_ndk_headers("purgeable_memory_header") { + dest_dir = "$ndk_headers_out_dir/purgeable_memory" + sources = [ "./purgeable_memory.h" ] +} + +ohos_ndk_library("libpurgeable_memory_ndk") { + output_name = "purgeable_memory_ndk" + output_extension = "z.so" + ndk_description_file = "./libpurgeable_memory.ndk.json" +} diff --git a/libpurgeablemem/interfaces/kits/c/libpurgeable_memory.ndk.json b/libpurgeablemem/interfaces/kits/c/libpurgeable_memory.ndk.json new file mode 100644 index 0000000000000000000000000000000000000000..02b15f0172891e9779c9a7db92cb4e1f5242addb --- /dev/null +++ b/libpurgeablemem/interfaces/kits/c/libpurgeable_memory.ndk.json @@ -0,0 +1,11 @@ +[ + { "name": "OH_PurgeableMemory_Create" }, + { "name": "OH_PurgeableMemory_Destroy" }, + { "name": "OH_PurgeableMemory_BeginRead" }, + { "name": "OH_PurgeableMemory_EndRead" }, + { "name": "OH_PurgeableMemory_BeginWrite" }, + { "name": "OH_PurgeableMemory_EndWrite" }, + { "name": "OH_PurgeableMemory_GetContent" }, + { "name": "OH_PurgeableMemory_ContentSize" }, + { "name": "OH_PurgeableMemory_AppendModify" } +] \ No newline at end of file diff --git a/libpurgeablemem/interfaces/kits/c/purgeable_memory.h b/libpurgeablemem/interfaces/kits/c/purgeable_memory.h new file mode 100644 index 0000000000000000000000000000000000000000..a76006452c3875c3fb69307e1724a558b7f21b53 --- /dev/null +++ b/libpurgeablemem/interfaces/kits/c/purgeable_memory.h @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup memory + * + * @brief provides memory management capabilities + * + * provides features include operations such as memory alloction, memory free, and so on + * + * @since 10 + * @version 1.0 + */ + +/** + * @file purgeable_memory.h + * + * @brief provides memory management capabilities of purgeable memory. + * + * provides features include create, begin read ,end read, begin write, end write, rebuild, and so on + * + * @since 10 + * @version 1.0 + */ + +#ifndef OHOS_UTILS_MEMORY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEMORY_H +#define OHOS_UTILS_MEMORY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEMORY_H + +#include /* bool */ +#include /* size_t */ + +#ifdef __cplusplus +extern "C" { +#endif /* End of #ifdef __cplusplus */ + +/* + * @brief Purgeable mem struct + * + * @since 10 + * @version 1.0 + */ +typedef struct PurgMem OH_PurgeableMemory; + +/* + * @brief: function pointer, it points to a function which is used to build content of a PurgMem obj. + * + * + * @param void *: data ptr, points to start address of a PurgMem obj's content. + * @param size_t: data size of the content. + * @param void *: other private parameters. + * @return: build content result, true means success, while false is fail. + * + * @since 10 + * @version 1.0 + */ +typedef bool (*OH_PurgeableMemory_ModifyFunc)(void *, size_t, void *); + +/* + * @brief: create a PurgMem obj. + * + * + * @param size: data size of a PurgMem obj's content. + * @param func: function pointer, it is used to recover data when the PurgMem obj's content is purged. + * @param funcPara: parameters used by @func. + * @return: a PurgMem obj. + * + * @since 10 + * @version 1.0 + */ +OH_PurgeableMemory *OH_PurgeableMemory_Create( + size_t size, OH_PurgeableMemory_ModifyFunc func, void *funcPara); + +/* + * @brief: destroy a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj to be destroyed. + * @return: true is success, while false is fail. return true if @purgObj is NULL. + * If return true, @purgObj will be set to NULL to avoid Use-After-Free. + * + * @since 10 + * @version 1.0 + */ +bool OH_PurgeableMemory_Destroy(OH_PurgeableMemory *purgObj); + +/* + * @brief: begin read a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @return: return true if @purgObj's content is present. + * If content is purged(no present), system will recover its data, + * return false if content is purged and recovered failed. + * While return true if content recover success. + * OS cannot reclaim the memory of @purgObj's content when this + * function return true, until PurgMemEndRead() is called. + * + * @since 10 + * @version 1.0 + */ +bool OH_PurgeableMemory_BeginRead(OH_PurgeableMemory *purgObj); + +/* + * @brief: end read a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * OS may reclaim the memory of @purgObj's content + * at a later time when this function returns. + * + * @since 10 + * @version 1.0 + */ +void OH_PurgeableMemory_EndRead(OH_PurgeableMemory *purgObj); + +/* + * @brief: begin write a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @return: return true if @purgObj's content is present. + * if content is purged(no present), system will recover its data, + * return false if content is purged and recovered failed. + * While return true if content is successfully recovered. + * OS cannot reclaim the memory of @purgObj's content when this + * function return true, until PurgMemEndWrite() is called. + * + * @since 10 + * @version 1.0 + */ +bool OH_PurgeableMemory_BeginWrite(OH_PurgeableMemory *purgObj); + +/* + * @brief: end write a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * OS may reclaim the memory of @purgObj's content + * at a later time when this function returns. + * + * @since 10 + * @version 1.0 + */ +void OH_PurgeableMemory_EndWrite(OH_PurgeableMemory *purgObj); + +/* + * @brief: get content ptr of a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @return: return start address of a PurgMem obj's content. + * Return NULL if @purgObj is NULL. + * This function should be protect by PurgMemBeginRead()/PurgMemEndRead() + * or PurgMemBeginWrite()/PurgMemEndWrite() + * + * @since 10 + * @version 1.0 + */ +void *OH_PurgeableMemory_GetContent(OH_PurgeableMemory *purgObj); + +/* + * @brief: get content size of a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @return: return content size of @purgObj. + * Return 0 if @purgObj is NULL. + * + * @since 10 + * @version 1.0 + */ +size_t OH_PurgeableMemory_ContentSize(OH_PurgeableMemory *purgObj); + +/* + * @brief: append a modify to a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @param size: data size of a PurgMem obj's content. + * @param func: function pointer, it will modify content of @PurgMem. + * @param funcPara: parameters used by @func. + * @return: append result, true is success, while false is fail. + * + * @since 10 + * @version 1.0 + */ +bool OH_PurgeableMemory_AppendModify(OH_PurgeableMemory *purgObj, + OH_PurgeableMemory_ModifyFunc func, void *funcPara); + +#ifdef __cplusplus +} +#endif /* End of #ifdef __cplusplus */ +#endif /* OHOS_UTILS_MEMORY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEMORY_H */ \ No newline at end of file