aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Stange <stange@google.com>2019-05-24 08:38:58 -0400
committerAnthony Stange <stange@google.com>2019-05-24 13:57:51 -0400
commit6dfcf4fc0be3caffd5a66a61b0020e12080dc32e (patch)
tree570cf782cca0bdad14397ad2b01452b6d18e055c
parenteb2d187cc3e76015a404ce3584d619f5968e9ac5 (diff)
downloadchre-6dfcf4fc0be3caffd5a66a61b0020e12080dc32e.tar.gz
Modify CHRE to allow loading nanoapps via a file
Loading via a file removes the need to allocate a temporary buffer. This is useful if multiple nanoapps need to be pushed to CHRE at the same time, but are too large to allocate space for all at once (e.g. preloaded nanoapps). Bug: 120610282 Test: Loaded all updated components and verified nanoapps were loaded and requests were served before the PAL comes online. Also verified code download path still works by loading geofence.napp w/ a modified gmscore. Change-Id: If1a58e033e7b8a20118d02b76f17c9e302b49e33
-rw-r--r--host/common/host_protocol_host.cc19
-rw-r--r--host/common/include/chre_host/fragmented_load_transaction.h4
-rw-r--r--host/common/include/chre_host/host_protocol_host.h18
-rw-r--r--platform/shared/host_protocol_chre.cc20
-rw-r--r--platform/shared/include/chre/platform/shared/host_protocol_chre.h16
-rw-r--r--platform/slpi/host_link.cc133
-rw-r--r--platform/slpi/include/chre/target_platform/platform_nanoapp_base.h42
-rw-r--r--platform/slpi/platform_nanoapp.cc53
8 files changed, 259 insertions, 46 deletions
diff --git a/host/common/host_protocol_host.cc b/host/common/host_protocol_host.cc
index b299c33f..f775c803 100644
--- a/host/common/host_protocol_host.cc
+++ b/host/common/host_protocol_host.cc
@@ -31,6 +31,8 @@ namespace fbs = ::chre::fbs;
namespace android {
namespace chre {
+// This is similar to getStringFromByteVector in host_protocol_chre.h. Ensure
+// that method's implementation is kept in sync with this.
const char *getStringFromByteVector(const std::vector<int8_t>& vec) {
constexpr int8_t kNullChar = static_cast<int8_t>('\0');
const char *str = nullptr;
@@ -98,7 +100,7 @@ void HostProtocolHost::encodeHubInfoRequest(FlatBufferBuilder& builder) {
void HostProtocolHost::encodeFragmentedLoadNanoappRequest(
flatbuffers::FlatBufferBuilder& builder,
const FragmentedLoadRequest& request) {
- encodeLoadNanoappRequest(
+ encodeLoadNanoappRequestForBinary(
builder, request.transactionId, request.appId, request.appVersion,
request.targetApiVersion, request.binary, request.fragmentId,
request.appTotalSizeBytes);
@@ -164,7 +166,7 @@ bool HostProtocolHost::mutateHostClientId(void *message, size_t messageLen,
return success;
}
-void HostProtocolHost::encodeLoadNanoappRequest(
+void HostProtocolHost::encodeLoadNanoappRequestForBinary(
FlatBufferBuilder& builder, uint32_t transactionId, uint64_t appId,
uint32_t appVersion, uint32_t targetApiVersion,
const std::vector<uint8_t>& nanoappBinary, uint32_t fragmentId,
@@ -176,5 +178,18 @@ void HostProtocolHost::encodeLoadNanoappRequest(
finalize(builder, fbs::ChreMessage::LoadNanoappRequest, request.Union());
}
+void HostProtocolHost::encodeLoadNanoappRequestForFile(
+ flatbuffers::FlatBufferBuilder& builder, uint32_t transactionId,
+ uint64_t appId, uint32_t appVersion, uint32_t targetApiVersion,
+ const char *nanoappBinaryName) {
+ const std::vector<uint8_t> emptyAppBinary;
+ auto appBinary = builder.CreateVector(emptyAppBinary);
+ auto appBinaryName = addStringAsByteVector(builder, nanoappBinaryName);
+ auto request = fbs::CreateLoadNanoappRequest(
+ builder, transactionId, appId, appVersion, targetApiVersion, appBinary,
+ 0 /* fragmentId */, 0 /* appTotalSizeBytes */, appBinaryName);
+ finalize(builder, fbs::ChreMessage::LoadNanoappRequest, request.Union());
+}
+
} // namespace chre
} // namespace android
diff --git a/host/common/include/chre_host/fragmented_load_transaction.h b/host/common/include/chre_host/fragmented_load_transaction.h
index dd2a21f9..c1475bd3 100644
--- a/host/common/include/chre_host/fragmented_load_transaction.h
+++ b/host/common/include/chre_host/fragmented_load_transaction.h
@@ -45,8 +45,8 @@ struct FragmentedLoadRequest {
FragmentedLoadRequest(
size_t fragmentId, uint32_t transactionId, uint64_t appId,
- uint32_t appVersion, uint32_t targetApiVersion,
- size_t appTotalSizeBytes, const std::vector<uint8_t>& binary)
+ uint32_t appVersion, uint32_t targetApiVersion, size_t appTotalSizeBytes,
+ const std::vector<uint8_t>& binary)
: fragmentId(fragmentId),
transactionId(transactionId),
appId(appId),
diff --git a/host/common/include/chre_host/host_protocol_host.h b/host/common/include/chre_host/host_protocol_host.h
index ba6508ae..f91fc463 100644
--- a/host/common/include/chre_host/host_protocol_host.h
+++ b/host/common/include/chre_host/host_protocol_host.h
@@ -34,6 +34,9 @@ namespace chre {
* Checks that a string encapsulated as a byte vector is null-terminated, and
* if it is, returns a pointer to the vector's data. Otherwise returns null.
*
+ * This is similar to getStringFromByteVector in host_protocol_chre.h. Ensure
+ * that method's implementation is kept in sync with this.
+ *
* @param vec Target vector, can be null
*
* @return Pointer to the vector's data, or null
@@ -184,7 +187,6 @@ class HostProtocolHost : public ::chre::HostProtocolCommon {
static bool mutateHostClientId(void *message, size_t messageLen,
uint16_t hostClientId);
- private:
/**
* Encodes a message requesting to load a nanoapp specified by the included
* binary payload and metadata.
@@ -192,11 +194,23 @@ class HostProtocolHost : public ::chre::HostProtocolCommon {
* @param builder A newly constructed FlatBufferBuilder that will be used to
* construct the message
*/
- static void encodeLoadNanoappRequest(
+ static void encodeLoadNanoappRequestForBinary(
flatbuffers::FlatBufferBuilder& builder, uint32_t transactionId,
uint64_t appId, uint32_t appVersion, uint32_t targetApiVersion,
const std::vector<uint8_t>& nanoappBinary, uint32_t fragmentId,
size_t appTotalSizeBytes);
+
+ /**
+ * Encodes a message requesting to load a nanoapp specified by the included
+ * binary filename and metadata.
+ *
+ * @param builder A newly constructed FlatBufferBuilder that will be used to
+ * construct the message
+ */
+ static void encodeLoadNanoappRequestForFile(
+ flatbuffers::FlatBufferBuilder& builder, uint32_t transactionId,
+ uint64_t appId, uint32_t appVersion, uint32_t targetApiVersion,
+ const char *nanoappBinaryName);
};
} // namespace chre
diff --git a/platform/shared/host_protocol_chre.cc b/platform/shared/host_protocol_chre.cc
index 57e4306a..57edab8e 100644
--- a/platform/shared/host_protocol_chre.cc
+++ b/platform/shared/host_protocol_chre.cc
@@ -28,6 +28,20 @@ using flatbuffers::Vector;
namespace chre {
+// This is similar to getStringFromByteVector in host_protocol_host.h. Ensure
+// that method's implementation is kept in sync with this.
+const char *getStringFromByteVector(const flatbuffers::Vector<int8_t> *vec) {
+ constexpr int8_t kNullChar = static_cast<int8_t>('\0');
+ const char *str = nullptr;
+
+ // Check that the vector is present, non-empty, and null-terminated
+ if (vec != nullptr && vec->size() > 0 && (*vec)[vec->size() - 1] == kNullChar) {
+ str = reinterpret_cast<const char *>(vec->Data());
+ }
+
+ return str;
+}
+
bool HostProtocolChre::decodeMessageFromHost(const void *message,
size_t messageLen) {
bool success = verifyMessage(message, messageLen);
@@ -63,11 +77,13 @@ bool HostProtocolChre::decodeMessageFromHost(const void *message,
const auto *request = static_cast<const fbs::LoadNanoappRequest *>(
container->message());
const flatbuffers::Vector<uint8_t> *appBinary = request->app_binary();
+ const char *appBinaryFilename = getStringFromByteVector(
+ request->app_binary_file_name());
HostMessageHandlers::handleLoadNanoappRequest(
hostClientId, request->transaction_id(), request->app_id(),
request->app_version(), request->target_api_version(),
- appBinary->data(), appBinary->size(), request->fragment_id(),
- request->total_app_size());
+ appBinary->data(), appBinary->size(), appBinaryFilename,
+ request->fragment_id(), request->total_app_size());
break;
}
diff --git a/platform/shared/include/chre/platform/shared/host_protocol_chre.h b/platform/shared/include/chre/platform/shared/host_protocol_chre.h
index 764d7d8b..aad53613 100644
--- a/platform/shared/include/chre/platform/shared/host_protocol_chre.h
+++ b/platform/shared/include/chre/platform/shared/host_protocol_chre.h
@@ -28,6 +28,19 @@ namespace chre {
typedef flatbuffers::Offset<fbs::NanoappListEntry> NanoappListEntryOffset;
/**
+ * Checks that a string encapsulated as a byte vector is null-terminated, and
+ * if it is, returns a pointer to the vector's data. Otherwise returns null.
+ *
+ * This is similar to getStringFromByteVector in host_protocol_host.h. Ensure
+ * that method's implementation is kept in sync with this.
+ *
+ * @param vec Target vector, can be null
+ *
+ * @return Pointer to the vector's data, or null
+ */
+const char *getStringFromByteVector(const flatbuffers::Vector<int8_t> *vec);
+
+/**
* These methods are called from decodeMessageFromHost() and must be implemented
* by the code that calls it to handle parsed messages.
*/
@@ -44,7 +57,8 @@ class HostMessageHandlers {
static void handleLoadNanoappRequest(
uint16_t hostClientId, uint32_t transactionId, uint64_t appId,
uint32_t appVersion, uint32_t targetApiVersion, const void *buffer,
- size_t bufferLen, uint32_t fragmentId, size_t appBinaryLen);
+ size_t bufferLen, const char *appFileName, uint32_t fragmentId,
+ size_t appBinaryLen);
static void handleUnloadNanoappRequest(
uint16_t hostClientId, uint32_t transactionId, uint64_t appId,
diff --git a/platform/slpi/host_link.cc b/platform/slpi/host_link.cc
index 6d31a8a0..2b928974 100644
--- a/platform/slpi/host_link.cc
+++ b/platform/slpi/host_link.cc
@@ -490,6 +490,97 @@ void setTimeSyncRequestTimer(Nanoseconds delay) {
}
/**
+ * Helper function that prepares a nanoapp that can be loaded into the system
+ * from a file stored on disk.
+ *
+ * @param hostClientId the ID of client that originated this transaction
+ * @param transactionId the ID of the transaction
+ * @param appId the ID of the app to load
+ * @param appVersion the version of the app to load
+ * @param targetApiVersion the API version this nanoapp is targeted for
+ * @param appFilename Null-terminated ASCII string containing the file name that
+ * contains the app binary to be loaded.
+ *
+ * @return A valid pointer to a nanoapp that can be loaded into the system. A
+ * nullptr if the preparation process fails.
+ */
+UniquePtr<Nanoapp> handleLoadNanoappFile(
+ uint16_t hostClientId, uint32_t transactionId, uint64_t appId,
+ uint32_t appVersion, uint32_t targetApiVersion, const char *appFilename) {
+ LOGD("Load nanoapp request for app ID 0x%016" PRIx64 " ver 0x%" PRIx32
+ " target API 0x%08" PRIx32 " (txnId %" PRIu32 " client %"
+ PRIu16 ")", appId, appVersion, targetApiVersion, transactionId,
+ hostClientId);
+
+ auto nanoapp = MakeUnique<Nanoapp>();
+
+ if (nanoapp.isNull()) {
+ LOG_OOM();
+ } else if (!nanoapp->setAppInfo(appId, appVersion, appFilename)
+ || !nanoapp->isLoaded()) {
+ nanoapp.reset(nullptr);
+ }
+
+ return nanoapp;
+}
+
+/**
+ * Helper function that prepares a nanoapp that can be loaded into the system
+ * from a buffer sent over in 1 or more fragments.
+ *
+ * @param hostClientId the ID of client that originated this transaction
+ * @param transactionId the ID of the transaction
+ * @param appId the ID of the app to load
+ * @param appVersion the version of the app to load
+ * @param targetApiVersion the API version this nanoapp is targeted for
+ * @param buffer the nanoapp binary data. May be only part of the nanoapp's
+ * binary if it's being sent over multiple fragments
+ * @param bufferLen the size of buffer in bytes
+ * @param fragmentId the identifier indicating which fragment is being loaded
+ * @param appBinaryLen the full size of the nanoapp binary to be loaded
+ *
+ * @return A valid pointer to a nanoapp that can be loaded into the system. A
+ * nullptr if the preparation process fails.
+ */
+UniquePtr<Nanoapp> handleLoadNanoappData(
+ uint16_t hostClientId, uint32_t transactionId, uint64_t appId,
+ uint32_t appVersion, uint32_t targetApiVersion, const void *buffer,
+ size_t bufferLen, uint32_t fragmentId, size_t appBinaryLen) {
+ static NanoappLoadManager sLoadManager;
+
+ bool success = true;
+ if (fragmentId == 0 || fragmentId == 1) { // first fragment
+ size_t totalAppBinaryLen = (fragmentId == 0) ? bufferLen : appBinaryLen;
+ LOGD("Load nanoapp request for app ID 0x%016" PRIx64 " ver 0x%" PRIx32
+ " target API 0x%08" PRIx32 " size %zu (txnId %" PRIu32 " client %"
+ PRIu16 ")", appId, appVersion, targetApiVersion, totalAppBinaryLen,
+ transactionId, hostClientId);
+
+ if (sLoadManager.hasPendingLoadTransaction()) {
+ FragmentedLoadInfo info = sLoadManager.getTransactionInfo();
+ sendFragmentResponse(
+ info.hostClientId, info.transactionId, 0 /* fragmentId */,
+ false /* success */);
+ sLoadManager.markFailure();
+ }
+
+ success = sLoadManager.prepareForLoad(
+ hostClientId, transactionId, appId, appVersion, totalAppBinaryLen);
+ }
+ success &= sLoadManager.copyNanoappFragment(
+ hostClientId, transactionId, (fragmentId == 0) ? 1 : fragmentId, buffer,
+ bufferLen);
+
+ UniquePtr<Nanoapp> nanoapp;
+ if (!sLoadManager.isLoadComplete()) {
+ sendFragmentResponse(hostClientId, transactionId, fragmentId, success);
+ } else {
+ nanoapp = sLoadManager.releaseNanoapp();
+ }
+ return nanoapp;
+}
+
+/**
* FastRPC method invoked by the host to block on messages
*
* @param buffer Output buffer to populate with message data
@@ -699,36 +790,20 @@ void HostMessageHandlers::handleNanoappListRequest(uint16_t hostClientId) {
void HostMessageHandlers::handleLoadNanoappRequest(
uint16_t hostClientId, uint32_t transactionId, uint64_t appId,
uint32_t appVersion, uint32_t targetApiVersion, const void *buffer,
- size_t bufferLen, uint32_t fragmentId, size_t appBinaryLen) {
- static NanoappLoadManager sLoadManager;
-
- bool success = true;
- if (fragmentId == 0 || fragmentId == 1) { // first fragment
- size_t totalAppBinaryLen = (fragmentId == 0) ? bufferLen : appBinaryLen;
- LOGD("Load nanoapp request for app ID 0x%016" PRIx64 " ver 0x%" PRIx32
- " target API 0x%08" PRIx32 " size %zu (txnId %" PRIu32 " client %" PRIu16
- ")", appId, appVersion, targetApiVersion, totalAppBinaryLen,
- transactionId, hostClientId);
-
- if (sLoadManager.hasPendingLoadTransaction()) {
- FragmentedLoadInfo info = sLoadManager.getTransactionInfo();
- sendFragmentResponse(
- info.hostClientId, info.transactionId, 0 /* fragmentId */,
- false /* success */);
- sLoadManager.markFailure();
- }
-
- success = sLoadManager.prepareForLoad(
- hostClientId, transactionId, appId, appVersion, totalAppBinaryLen);
+ size_t bufferLen, const char *appFileName, uint32_t fragmentId,
+ size_t appBinaryLen) {
+ UniquePtr<Nanoapp> pendingNanoapp;
+ if (appFileName != nullptr) {
+ pendingNanoapp = handleLoadNanoappFile(
+ hostClientId, transactionId, appId, appVersion, targetApiVersion,
+ appFileName);
+ } else {
+ pendingNanoapp = handleLoadNanoappData(
+ hostClientId, transactionId, appId, appVersion, targetApiVersion,
+ buffer, bufferLen, fragmentId, appBinaryLen);
}
- success &= sLoadManager.copyNanoappFragment(
- hostClientId, transactionId, (fragmentId == 0) ? 1 : fragmentId, buffer,
- bufferLen);
- if (!sLoadManager.isLoadComplete()) {
- sendFragmentResponse(hostClientId, transactionId, fragmentId, success);
- } else {
- UniquePtr<Nanoapp> nanoapp = sLoadManager.releaseNanoapp();
+ if (!pendingNanoapp.isNull()) {
auto cbData = MakeUnique<LoadNanoappCallbackData>();
if (cbData.isNull()) {
LOG_OOM();
@@ -737,7 +812,7 @@ void HostMessageHandlers::handleLoadNanoappRequest(
cbData->hostClientId = hostClientId;
cbData->appId = appId;
cbData->fragmentId = fragmentId;
- cbData->nanoapp = std::move(nanoapp);
+ cbData->nanoapp = std::move(pendingNanoapp);
// Note that if this fails, we'll generate the error response in
// the normal deferred callback
diff --git a/platform/slpi/include/chre/target_platform/platform_nanoapp_base.h b/platform/slpi/include/chre/target_platform/platform_nanoapp_base.h
index 063116d5..72aeb611 100644
--- a/platform/slpi/include/chre/target_platform/platform_nanoapp_base.h
+++ b/platform/slpi/include/chre/target_platform/platform_nanoapp_base.h
@@ -31,6 +31,18 @@ namespace chre {
class PlatformNanoappBase {
public:
/**
+ * Sets app info that will be used later when the app is loaded into the
+ * system.
+ *
+ * @param appId The unique app identifier associated with this binary
+ * @param appVersion An application-defined version number
+ * @param appFilename The filename of the app that should be loaded from disk
+ *
+ * @return true if the info was successfully stored
+ */
+ bool setAppInfo(uint64_t appId, uint32_t appVersion, const char *appFilename);
+
+ /**
* Reserves buffer space for a nanoapp's binary. This method should be called
* before copyNanoappFragment is called.
*
@@ -62,9 +74,10 @@ class PlatformNanoappBase {
void loadStatic(const struct chreNslNanoappInfo *appInfo);
/**
- * @return true if the app's binary data is resident in memory, i.e. all
- * binary fragments are loaded through copyNanoappFragment, or
- * loadFromFile/loadStatic() was successful
+ * @return true if the app's binary data is resident in memory or if the app's
+ * filename is saved, i.e. all binary fragments are loaded through
+ * copyNanoappFragment, loadFromFile/loadStatic() was successful, or
+ * setAppInfo was successful.
*/
bool isLoaded() const;
@@ -96,6 +109,11 @@ class PlatformNanoappBase {
void *mAppBinary = nullptr;
size_t mAppBinaryLen = 0;
+ //! Null-terminated ASCII string containing the file name that contains the
+ //! app binary to be loaded. This is used over mAppBinary to load the nanoapp
+ //! if set.
+ char *mAppFilename = nullptr;
+
//! The dynamic shared object (DSO) handle returned by dlopenbuf()
void *mDsoHandle = nullptr;
@@ -130,6 +148,24 @@ class PlatformNanoappBase {
bool openNanoappFromBuffer();
/**
+ * Calls dlopen on the app file name, and fetches and validates the app info
+ * pointer. This will result in execution of any on-load handlers (e.g. static
+ * global constructors) in the nanoapp.
+ *
+ * @return true if the app was opened successfully and the app info structure
+ * passed validation
+ */
+ bool openNanoappFromFile();
+
+ /**
+ * Loads the nanoapp symbols from the currently loaded binary and verifies
+ * they match the expected information the nanoapp should have.
+ *
+ * @return true if the app info structure passed validation.
+ */
+ bool verifyNanoappInfo();
+
+ /**
* Releases the DSO handle if it was active, by calling dlclose(). This will
* result in execution of any unload handlers in the nanoapp.
*/
diff --git a/platform/slpi/platform_nanoapp.cc b/platform/slpi/platform_nanoapp.cc
index 0fa302db..7c306018 100644
--- a/platform/slpi/platform_nanoapp.cc
+++ b/platform/slpi/platform_nanoapp.cc
@@ -170,6 +170,25 @@ void PlatformNanoapp::end() {
closeNanoapp();
}
+bool PlatformNanoappBase::setAppInfo(
+ uint64_t appId, uint32_t appVersion, const char *appFilename) {
+ CHRE_ASSERT(!isLoaded());
+ mExpectedAppId = appId;
+ mExpectedAppVersion = appVersion;
+ size_t appFilenameLen = strlen(appFilename) + 1;
+ mAppFilename = static_cast<char *>(memoryAllocBigImage(appFilenameLen));
+
+ bool success = false;
+ if (mAppFilename == nullptr) {
+ LOG_OOM();
+ } else {
+ memcpy(static_cast<void *>(mAppFilename), appFilename, appFilenameLen);
+ success = true;
+ }
+
+ return success;
+}
+
bool PlatformNanoappBase::reserveBuffer(
uint64_t appId, uint32_t appVersion, size_t appBinaryLen) {
CHRE_ASSERT(!isLoaded());
@@ -220,7 +239,7 @@ void PlatformNanoappBase::loadStatic(const struct chreNslNanoappInfo *appInfo) {
bool PlatformNanoappBase::isLoaded() const {
return (mIsStatic || (mAppBinary != nullptr && mBytesLoaded == mAppBinaryLen)
- || mDsoHandle != nullptr);
+ || mDsoHandle != nullptr || mAppFilename != nullptr);
}
bool PlatformNanoappBase::isUimgApp() const {
@@ -244,10 +263,17 @@ bool PlatformNanoappBase::openNanoapp() {
success = true;
} else if (mAppBinary != nullptr) {
success = openNanoappFromBuffer();
+ } else if (mAppFilename != nullptr) {
+ success = openNanoappFromFile();
} else {
CHRE_ASSERT(false);
}
+ // Ensure any allocated memory hanging around is properly cleaned up.
+ if (!success) {
+ closeNanoapp();
+ }
+
// Save this flag locally since it may be referenced while the system is in
// micro-image
if (mAppInfo != nullptr) {
@@ -260,7 +286,6 @@ bool PlatformNanoappBase::openNanoapp() {
bool PlatformNanoappBase::openNanoappFromBuffer() {
CHRE_ASSERT(mAppBinary != nullptr);
CHRE_ASSERT_LOG(mDsoHandle == nullptr, "Re-opening nanoapp");
- bool success = false;
// Populate a filename string (just a requirement of the dlopenbuf API)
constexpr size_t kMaxFilenameLen = 17;
@@ -270,8 +295,28 @@ bool PlatformNanoappBase::openNanoappFromBuffer() {
mDsoHandle = dlopenbuf(
filename, static_cast<const char *>(mAppBinary),
static_cast<int>(mAppBinaryLen), RTLD_NOW);
+ memoryFreeBigImage(mAppBinary);
+ mAppBinary = nullptr;
+
+ return verifyNanoappInfo();
+}
+
+bool PlatformNanoappBase::openNanoappFromFile() {
+ CHRE_ASSERT(mAppFilename != nullptr);
+ CHRE_ASSERT_LOG(mDsoHandle == nullptr, "Re-opening nanoapp");
+
+ mDsoHandle = dlopen(mAppFilename, RTLD_NOW);
+ memoryFreeBigImage(mAppFilename);
+ mAppFilename = nullptr;
+
+ return verifyNanoappInfo();
+}
+
+bool PlatformNanoappBase::verifyNanoappInfo() {
+ bool success = false;
+
if (mDsoHandle == nullptr) {
- LOGE("Failed to load nanoapp: %s", dlerror());
+ LOGE("No nanoapp info to verify: %s", dlerror());
} else {
mAppInfo = static_cast<const struct chreNslNanoappInfo *>(
dlsym(mDsoHandle, CHRE_NSL_DSO_NANOAPP_INFO_SYMBOL_NAME));
@@ -286,8 +331,6 @@ bool PlatformNanoappBase::openNanoappFromBuffer() {
PRIx32 " (%s) uimg %d system %d", mAppInfo->name, mAppInfo->appId,
mAppInfo->appVersion, getAppVersionString(),
mAppInfo->isTcmNanoapp, mAppInfo->isSystemNanoapp);
- memoryFreeBigImage(mAppBinary);
- mAppBinary = nullptr;
}
}
}