Snap for 11520864 from 0f2ba27093dcdef05091cb4ee3b21bb4473be31c to 24Q2-release
Change-Id: I3590c6f859bbdf3daa0b7ee1c220aba68dafc9f2
diff --git a/platform/shared/include/chre/platform/shared/nanoapp_loader.h b/platform/shared/include/chre/platform/shared/nanoapp_loader.h
index ee788bf..d9ae669 100644
--- a/platform/shared/include/chre/platform/shared/nanoapp_loader.h
+++ b/platform/shared/include/chre/platform/shared/nanoapp_loader.h
@@ -71,11 +71,6 @@
public:
NanoappLoader() = delete;
- explicit NanoappLoader(void *elfInput, bool mapIntoTcm) {
- mBinary = static_cast<uint8_t *>(elfInput);
- mIsTcmBinary = mapIntoTcm;
- }
-
/**
* Factory method to create a NanoappLoader Instance after loading
* the buffer containing the ELF binary.
@@ -86,7 +81,7 @@
* @return Class instance on successful load and verification,
* nullptr otherwise.
*/
- static void *create(void *elfInput, bool mapIntoTcm);
+ static NanoappLoader *create(void *elfInput, bool mapIntoTcm);
/**
* Closes and destroys the NanoappLoader instance.
@@ -152,10 +147,17 @@
bool getTokenDatabaseSectionInfo(uint32_t *offset, size_t *size);
private:
+ explicit NanoappLoader(void *elfInput, bool mapIntoTcm) {
+ mBinary = static_cast<uint8_t *>(elfInput);
+ mIsTcmBinary = mapIntoTcm;
+ }
+
/**
* Opens the ELF binary. This maps the binary into memory, resolves symbols,
* and invokes any static initializers.
*
+ * <p>This function must be called before any symbol-finding functions.
+ *
* @return true if all required opening steps were completed.
*/
bool open();
@@ -367,7 +369,9 @@
* @return The ELF header for the binary being loaded. nullptr if it doesn't
* exist or no binary is being loaded.
*/
- ElfHeader *getElfHeader();
+ ElfHeader *getElfHeader() {
+ return reinterpret_cast<ElfHeader *>(mBinary);
+ }
/**
* @return The array of program headers for the binary being loaded. nullptr
@@ -399,7 +403,10 @@
static ElfWord getDynEntry(DynamicHeader *dyn, int field);
/**
- * Handle reolcation for entries in the specified table.
+ * Handle relocation for entries in the specified table.
+ *
+ * <p> this function must return true if the table is not required or is
+ * empty. If the entry is present when not expected, it must return false.
*
* @param dyn The dynamic header for the binary.
* @param tableTag The dynamic tag (DT_x) of the relocation table.
diff --git a/platform/shared/nanoapp_loader.cc b/platform/shared/nanoapp_loader.cc
index eef5da9..19b11b7 100644
--- a/platform/shared/nanoapp_loader.cc
+++ b/platform/shared/nanoapp_loader.cc
@@ -273,20 +273,28 @@
} // namespace
-void *NanoappLoader::create(void *elfInput, bool mapIntoTcm) {
- void *instance = nullptr;
- NanoappLoader *loader = memoryAllocDram<NanoappLoader>(elfInput, mapIntoTcm);
- if (loader != nullptr) {
- if (loader->open()) {
- instance = loader;
- } else {
- memoryFreeDram(loader);
- }
- } else {
- LOG_OOM();
+NanoappLoader *NanoappLoader::create(void *elfInput, bool mapIntoTcm) {
+ if (elfInput == nullptr) {
+ LOGE("Elf header must not be null");
+ return nullptr;
}
- return instance;
+ auto *loader =
+ static_cast<NanoappLoader *>(memoryAllocDram(sizeof(NanoappLoader)));
+ if (loader == nullptr) {
+ LOG_OOM();
+ return nullptr;
+ }
+ new (loader) NanoappLoader(elfInput, mapIntoTcm);
+
+ if (loader->open()) {
+ return loader;
+ }
+
+ // Call the destructor explicitly as memoryFreeDram() never calls it.
+ loader->~NanoappLoader();
+ memoryFreeDram(loader);
+ return nullptr;
}
void NanoappLoader::destroy(NanoappLoader *loader) {
@@ -319,33 +327,26 @@
}
bool NanoappLoader::open() {
- bool success = false;
- if (mBinary != nullptr) {
- if (!copyAndVerifyHeaders()) {
- LOGE("Failed to verify headers");
- } else if (!createMappings()) {
- LOGE("Failed to create mappings");
- } else if (!fixRelocations()) {
- LOGE("Failed to fix relocations");
- } else if (!resolveGot()) {
- LOGE("Failed to resolve GOT");
+ if (!copyAndVerifyHeaders()) {
+ LOGE("Failed to copy and verify elf headers");
+ } else if (!createMappings()) {
+ LOGE("Failed to create mappings");
+ } else if (!fixRelocations()) {
+ LOGE("Failed to fix relocations");
+ } else if (!resolveGot()) {
+ LOGE("Failed to resolve GOT");
+ } else {
+ // Wipe caches before calling init array to ensure initializers are not in
+ // the data cache.
+ wipeSystemCaches(reinterpret_cast<uintptr_t>(mMapping), mMemorySpan);
+ if (!callInitArray()) {
+ LOGE("Failed to perform static init");
} else {
- // Wipe caches before calling init array to ensure initializers are not in
- // the data cache.
- wipeSystemCaches(reinterpret_cast<uintptr_t>(mMapping), mMemorySpan);
- if (!callInitArray()) {
- LOGE("Failed to perform static init");
- } else {
- success = true;
- }
+ return true;
}
}
-
- if (!success) {
- freeAllocatedData();
- }
-
- return success;
+ freeAllocatedData();
+ return false;
}
void NanoappLoader::close() {
@@ -444,7 +445,6 @@
}
bool NanoappLoader::verifyElfHeader() {
- bool success = false;
ElfHeader *elfHeader = getElfHeader();
if (elfHeader != nullptr && (elfHeader->e_ident[EI_MAG0] == ELFMAG0) &&
(elfHeader->e_ident[EI_MAG1] == ELFMAG1) &&
@@ -457,9 +457,9 @@
(elfHeader->e_version == EV_CURRENT) &&
(elfHeader->e_machine == CHRE_LOADER_ARCH) &&
(elfHeader->e_type == ET_DYN)) {
- success = true;
+ return true;
}
- return success;
+ return false;
}
bool NanoappLoader::verifyProgramHeaders() {
@@ -495,29 +495,12 @@
return rv;
}
-ElfHeader *NanoappLoader::getElfHeader() {
- return reinterpret_cast<ElfHeader *>(mBinary);
-}
-
ProgramHeader *NanoappLoader::getProgramHeaderArray() {
- ElfHeader *elfHeader = getElfHeader();
- ProgramHeader *programHeader = nullptr;
- if (elfHeader != nullptr) {
- programHeader =
- reinterpret_cast<ProgramHeader *>(mBinary + elfHeader->e_phoff);
- }
-
- return programHeader;
+ return reinterpret_cast<ProgramHeader *>(mBinary + getElfHeader()->e_phoff);
}
size_t NanoappLoader::getProgramHeaderArraySize() {
- ElfHeader *elfHeader = getElfHeader();
- size_t arraySize = 0;
- if (elfHeader != nullptr) {
- arraySize = elfHeader->e_phnum;
- }
-
- return arraySize;
+ return getElfHeader()->e_phnum;
}
bool NanoappLoader::verifyDynamicTables() {
@@ -541,11 +524,7 @@
}
bool NanoappLoader::copyAndVerifyHeaders() {
- size_t offset = 0;
- CHRE_ASSERT(mBinary != nullptr);
-
// Verify the ELF Header
- ElfHeader *elfHeader = getElfHeader();
if (!verifyElfHeader()) {
LOGE("ELF header is invalid");
return false;
@@ -558,7 +537,7 @@
}
// Load Section Headers
- offset = elfHeader->e_shoff;
+ ElfHeader *elfHeader = getElfHeader();
size_t sectionHeaderSizeBytes = sizeof(SectionHeader) * elfHeader->e_shnum;
mSectionHeadersPtr =
static_cast<SectionHeader *>(memoryAllocDram(sectionHeaderSizeBytes));
@@ -566,7 +545,8 @@
LOG_OOM();
return false;
}
- memcpy(mSectionHeadersPtr, (mBinary + offset), sectionHeaderSizeBytes);
+ memcpy(mSectionHeadersPtr, (mBinary + elfHeader->e_shoff),
+ sectionHeaderSizeBytes);
mNumSectionHeaders = elfHeader->e_shnum;
// Load section header names
@@ -592,7 +572,6 @@
// ELF needs pt_load segments to be in contiguous ascending order of
// virtual addresses. So the first and last segs can be used to
// calculate the entire address span of the image.
- ElfHeader *elfHeader = getElfHeader();
ProgramHeader *programHeaderArray = getProgramHeaderArray();
size_t numProgramHeaders = getProgramHeaderArraySize();
const ProgramHeader *first = &programHeaderArray[0];
@@ -611,9 +590,9 @@
// first byte of a valid load segment can't be greater than the
// program header offset
bool valid =
- (first->p_offset < elfHeader->e_phoff) &&
- (first->p_filesz >=
- (elfHeader->e_phoff + (numProgramHeaders * sizeof(ProgramHeader))));
+ (first->p_offset < getElfHeader()->e_phoff) &&
+ (first->p_filesz >= (getElfHeader()->e_phoff +
+ (numProgramHeaders * sizeof(ProgramHeader))));
if (!valid) {
LOGE("Load segment program header validation failed");
} else {
@@ -693,7 +672,6 @@
if (symbol == nullptr || symbol->st_shndx == SHN_UNDEF) {
return nullptr;
}
-
return mMapping + symbol->st_value;
}
@@ -759,25 +737,14 @@
bool NanoappLoader::fixRelocations() {
DynamicHeader *dyn = getDynamicHeader();
- ProgramHeader *roSeg = getFirstRoSegHeader();
-
- bool success = false;
- if ((dyn == nullptr) || (roSeg == nullptr)) {
- LOGE("Mandatory headers missing from shared object, aborting load");
+ if (dyn == nullptr) {
+ LOGE("Dynamic headers are missing from shared object");
}
-
- // Must return true if it table is not required or is empty. If
- // the entry is present when not expected, this must return false.
- success = relocateTable(dyn, DT_RELA);
- if (success) {
- success = relocateTable(dyn, DT_REL);
+ if (relocateTable(dyn, DT_RELA) && relocateTable(dyn, DT_REL)) {
+ return true;
}
-
- if (!success) {
- LOGE("Unable to resolve all symbols in the binary");
- }
-
- return success;
+ LOGE("Unable to resolve all symbols in the binary");
+ return false;
}
void NanoappLoader::callAtexitFunctions() {