/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * 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 <dlfcn.h>
#include <cctype>
#include <cmath>
#include <cstring>

#include "chre/platform/shared/nanoapp_loader.h"

#include "ash.h"
#include "chre.h"
#include "chre/platform/assert.h"
#include "chre/platform/shared/debug_dump.h"
#include "chre/platform/shared/memory.h"
#include "chre/target_platform/platform_cache_management.h"
#include "chre/util/dynamic_vector.h"
#include "chre/util/macros.h"

#ifndef CHRE_LOADER_ARCH
#define CHRE_LOADER_ARCH EM_ARM
#endif  // CHRE_LOADER_ARCH

namespace chre {
namespace {

using ElfHeader = ElfW(Ehdr);
using ProgramHeader = ElfW(Phdr);

struct ExportedData {
  void *data;
  const char *dataName;
};

//! If non-null, a nanoapp is currently being loaded. This allows certain C
//! functions to access the nanoapp if called during static init.
NanoappLoader *gCurrentlyLoadingNanoapp = nullptr;
//! Indicates whether a failure occurred during static initialization.
bool gStaticInitFailure = false;

// The new operator is used by singleton.h which causes the delete operator to
// be undefined in nanoapp binaries even though it's unused. Define this in case
// a nanoapp actually tries to use the operator.
void deleteOverride(void *ptr) {
  FATAL_ERROR("Nanoapp tried to free %p through delete operator", ptr);
}

// atexit is used to register functions that must be called when a binary is
// removed from the system.
int atexitOverride(void (*function)(void)) {
  LOGV("atexit invoked with %p", function);
  if (gCurrentlyLoadingNanoapp == nullptr) {
    CHRE_ASSERT_LOG(false,
                    "atexit is only supported during static initialization.");
    return -1;
  }

  gCurrentlyLoadingNanoapp->registerAtexitFunction(function);
  return 0;
}

// The following functions from the cmath header need to be overridden, since
// they're overloaded functions, and we need to specify explicit types of the
// template for the compiler.
double frexpOverride(double value, int *exp) {
  return frexp(value, exp);
}

double sinOverride(double rad) {
  return sin(rad);
}

double asinOverride(double val) {
  return asin(val);
}

double cosOverride(double rad) {
  return cos(rad);
}

float sqrtOverride(float val) {
  return sqrt(val);
}

// This function is required to be exposed to nanoapps to handle errors from
// invoking virtual functions.
void __cxa_pure_virtual(void) {
  chreAbort(CHRE_ERROR /* abortCode */);
}

#define ADD_EXPORTED_SYMBOL(function_name, function_string) \
  { reinterpret_cast<void *>(function_name), function_string }
#define ADD_EXPORTED_C_SYMBOL(function_name) \
  ADD_EXPORTED_SYMBOL(function_name, STRINGIFY(function_name))

// TODO(karthikmb/stange): While this array was hand-coded for simple
// "hello-world" prototyping, the list of exported symbols must be
// generated to minimize runtime errors and build breaks.
const ExportedData gExportedData[] = {
    /* libmath overrrides and symbols */
    ADD_EXPORTED_SYMBOL(asinOverride, "asin"),
    ADD_EXPORTED_SYMBOL(cosOverride, "cos"),
    ADD_EXPORTED_SYMBOL(frexpOverride, "frexp"),
    ADD_EXPORTED_SYMBOL(sinOverride, "sin"),
    ADD_EXPORTED_SYMBOL(sqrtOverride, "sqrt"),
    ADD_EXPORTED_C_SYMBOL(atan2f),
    ADD_EXPORTED_C_SYMBOL(expf),
    ADD_EXPORTED_C_SYMBOL(fmodf),
    ADD_EXPORTED_C_SYMBOL(sqrtf),
    ADD_EXPORTED_C_SYMBOL(tanhf),
    /* libc overrides and symbols */
    ADD_EXPORTED_C_SYMBOL(__cxa_pure_virtual),
    ADD_EXPORTED_SYMBOL(atexitOverride, "atexit"),
    ADD_EXPORTED_SYMBOL(deleteOverride, "_ZdlPv"),
    // TODO(b/151847750): Remove export once nanoapps are migrated to C symbol.
    ADD_EXPORTED_SYMBOL(dlsym, "_Z5dlsymPvPKc"),
    ADD_EXPORTED_C_SYMBOL(dlsym),
    ADD_EXPORTED_C_SYMBOL(memcmp),
    ADD_EXPORTED_C_SYMBOL(memcpy),
    ADD_EXPORTED_C_SYMBOL(memmove),
    ADD_EXPORTED_C_SYMBOL(memset),
    ADD_EXPORTED_C_SYMBOL(strcmp),
    ADD_EXPORTED_C_SYMBOL(strlen),
    ADD_EXPORTED_C_SYMBOL(strncmp),
    ADD_EXPORTED_C_SYMBOL(tolower),
    /* ash symbols */
    ADD_EXPORTED_C_SYMBOL(ashLoadCalibrationParams),
    ADD_EXPORTED_C_SYMBOL(ashSaveCalibrationParams),
    ADD_EXPORTED_C_SYMBOL(ashSetCalibration),
    /* CHRE symbols */
    ADD_EXPORTED_C_SYMBOL(chreAbort),
    ADD_EXPORTED_C_SYMBOL(chreAudioConfigureSource),
    ADD_EXPORTED_C_SYMBOL(chreAudioGetSource),
    ADD_EXPORTED_C_SYMBOL(chreConfigureDebugDumpEvent),
    ADD_EXPORTED_C_SYMBOL(chreConfigureHostSleepStateEvents),
    ADD_EXPORTED_C_SYMBOL(chreConfigureNanoappInfoEvents),
    ADD_EXPORTED_C_SYMBOL(chreGetApiVersion),
    ADD_EXPORTED_C_SYMBOL(chreGetAppId),
    ADD_EXPORTED_C_SYMBOL(chreGetInstanceId),
    ADD_EXPORTED_C_SYMBOL(chreGetEstimatedHostTimeOffset),
    ADD_EXPORTED_C_SYMBOL(chreGetNanoappInfoByAppId),
    ADD_EXPORTED_C_SYMBOL(chreGetPlatformId),
    ADD_EXPORTED_C_SYMBOL(chreGetSensorInfo),
    ADD_EXPORTED_C_SYMBOL(chreGetSensorSamplingStatus),
    ADD_EXPORTED_C_SYMBOL(chreGetTime),
    ADD_EXPORTED_C_SYMBOL(chreGnssGetCapabilities),
    ADD_EXPORTED_C_SYMBOL(chreGnssLocationSessionStartAsync),
    ADD_EXPORTED_C_SYMBOL(chreGnssLocationSessionStopAsync),
    ADD_EXPORTED_C_SYMBOL(chreGnssMeasurementSessionStartAsync),
    ADD_EXPORTED_C_SYMBOL(chreGnssMeasurementSessionStopAsync),
    ADD_EXPORTED_C_SYMBOL(chreHeapAlloc),
    ADD_EXPORTED_C_SYMBOL(chreHeapFree),
    ADD_EXPORTED_C_SYMBOL(chreIsHostAwake),
    ADD_EXPORTED_C_SYMBOL(chreLog),
    ADD_EXPORTED_C_SYMBOL(chreSendEvent),
    ADD_EXPORTED_C_SYMBOL(chreSendMessageToHostEndpoint),
    ADD_EXPORTED_C_SYMBOL(chreSensorConfigure),
    ADD_EXPORTED_C_SYMBOL(chreSensorFindDefault),
    ADD_EXPORTED_C_SYMBOL(chreTimerCancel),
    ADD_EXPORTED_C_SYMBOL(chreTimerSet),
    ADD_EXPORTED_C_SYMBOL(chreWifiConfigureScanMonitorAsync),
    ADD_EXPORTED_C_SYMBOL(chreWifiGetCapabilities),
    ADD_EXPORTED_C_SYMBOL(chreWifiRequestScanAsync),
    ADD_EXPORTED_C_SYMBOL(chreWwanGetCapabilities),
    ADD_EXPORTED_C_SYMBOL(chreWwanGetCellInfoAsync),
    ADD_EXPORTED_C_SYMBOL(platform_chreDebugDumpVaLog),
};

}  // 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();
  }

  return instance;
}

void NanoappLoader::destroy(NanoappLoader *loader) {
  loader->close();
  // TODO(b/151847750): Modify utilities to support free'ing from regions other
  // than SRAM.
  loader->~NanoappLoader();
  memoryFreeDram(loader);
}

void *NanoappLoader::findExportedSymbol(const char *name) {
  for (size_t i = 0; i < ARRAY_SIZE(gExportedData); i++) {
    if (strncmp(name, gExportedData[i].dataName,
                strlen(gExportedData[i].dataName)) == 0) {
      return gExportedData[i].data;
    }
  }

  LOGE("Unable to find %s", name);
  return nullptr;
}

bool NanoappLoader::open() {
  bool success = false;
  if (mBinary.dataPtr != 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");
    } else if (!callInitArray()) {
      LOGE("Failed to perform static init");
    } else {
      success = true;
    }
  }

  if (!success) {
    freeAllocatedData();
  } else {
    wipeSystemCaches();
  }

  return success;
}

void NanoappLoader::close() {
  callAtexitFunctions();
  callTerminatorArray();
  freeAllocatedData();
}

void *NanoappLoader::findSymbolByName(const char *name) {
  void *symbol = nullptr;
  uint8_t *index = mSymbolTablePtr;
  while (index < (mSymbolTablePtr + mSymbolTableSize)) {
    ElfSym *currSym = reinterpret_cast<ElfSym *>(index);
    const char *symbolName = &mStringTablePtr[currSym->st_name];

    if (strncmp(symbolName, name, strlen(name)) == 0) {
      symbol = reinterpret_cast<void *>(mMapping.data + currSym->st_value);
      break;
    }

    index += sizeof(ElfSym);
  }
  return symbol;
}

void NanoappLoader::registerAtexitFunction(void (*function)(void)) {
  if (!mAtexitFunctions.push_back(function)) {
    LOG_OOM();
    gStaticInitFailure = true;
  }
}

void NanoappLoader::mapBss(const ProgramHeader *hdr) {
  // if the memory size of this segment exceeds the file size zero fill the
  // difference.
  LOGV("Program Hdr mem sz: %zu file size: %zu", hdr->p_memsz, hdr->p_filesz);
  if (hdr->p_memsz > hdr->p_filesz) {
    ElfAddr endOfFile = hdr->p_vaddr + hdr->p_filesz + mLoadBias;
    ElfAddr endOfMem = hdr->p_vaddr + hdr->p_memsz + mLoadBias;
    if (endOfMem > endOfFile) {
      auto deltaMem = endOfMem - endOfFile;
      LOGV("Zeroing out %zu from page %p", deltaMem, endOfFile);
      memset(reinterpret_cast<void *>(endOfFile), 0, deltaMem);
    }
  }
}

bool NanoappLoader::callInitArray() {
  bool success = true;
  // Sets global variable used by atexit in case it's invoked as part of
  // initializing static data.
  gCurrentlyLoadingNanoapp = this;

  // TODO(b/151847750): ELF can have other sections like .init, .preinit, .fini
  // etc. Be sure to look for those if they end up being something that should
  // be supported for nanoapps.
  for (size_t i = 0; i < mNumSectionHeaders; ++i) {
    const char *name = getSectionHeaderName(mSectionHeadersPtr[i].sh_name);
    if (strncmp(name, kInitArrayName, strlen(kInitArrayName)) == 0) {
      LOGV("Invoking init function");
      uintptr_t initArray = reinterpret_cast<uintptr_t>(
          mLoadBias + mSectionHeadersPtr[i].sh_addr);
      uintptr_t offset = 0;
      while (offset < mSectionHeadersPtr[i].sh_size) {
        ElfAddr *funcPtr = reinterpret_cast<ElfAddr *>(initArray + offset);
        uintptr_t initFunction = reinterpret_cast<uintptr_t>(*funcPtr);
        ((void (*)())initFunction)();
        offset += sizeof(initFunction);
        if (gStaticInitFailure) {
          success = false;
          break;
        }
      }
      break;
    }
  }

  //! Reset global state so it doesn't leak into the next load.
  gCurrentlyLoadingNanoapp = nullptr;
  gStaticInitFailure = false;
  return success;
}

uintptr_t NanoappLoader::roundDownToAlign(uintptr_t virtualAddr) {
  return virtualAddr & -kBinaryAlignment;
}

void NanoappLoader::freeAllocatedData() {
  if (mIsTcmBinary) {
    memoryFree(mMapping.dataPtr);
  } else {
    memoryFreeDram(mMapping.dataPtr);
  }
  memoryFreeDram(mSectionHeadersPtr);
  memoryFreeDram(mSectionNamesPtr);
  memoryFreeDram(mSymbolTablePtr);
  memoryFreeDram(mStringTablePtr);
}

bool NanoappLoader::verifyElfHeader() {
  bool success = false;
  ElfHeader *elfHeader = getElfHeader();
  if (elfHeader != nullptr && (elfHeader->e_ident[EI_MAG0] == ELFMAG0) &&
      (elfHeader->e_ident[EI_MAG1] == ELFMAG1) &&
      (elfHeader->e_ident[EI_MAG2] == ELFMAG2) &&
      (elfHeader->e_ident[EI_MAG3] == ELFMAG3) &&
      (elfHeader->e_ehsize == sizeof(ElfHeader)) &&
      (elfHeader->e_phentsize == sizeof(ProgramHeader)) &&
      (elfHeader->e_shentsize == sizeof(SectionHeader)) &&
      (elfHeader->e_shstrndx < elfHeader->e_shnum) &&
      (elfHeader->e_version == EV_CURRENT) &&
      (elfHeader->e_machine == CHRE_LOADER_ARCH) &&
      (elfHeader->e_type == ET_DYN)) {
    success = true;
  }
  return success;
}

bool NanoappLoader::verifyProgramHeaders() {
  // This is a minimal check for now -
  // there should be at least one load segment.
  bool success = false;
  for (size_t i = 0; i < getProgramHeaderArraySize(); ++i) {
    if (getProgramHeaderArray()[i].p_type == PT_LOAD) {
      success = true;
      break;
    }
  }
  return success;
}

const char *NanoappLoader::getSectionHeaderName(size_t headerOffset) {
  if (headerOffset == 0) {
    return "";
  }

  return &mSectionNamesPtr[headerOffset];
}

NanoappLoader::SectionHeader *NanoappLoader::getSectionHeader(
    const char *headerName) {
  SectionHeader *rv = nullptr;
  for (size_t i = 0; i < mNumSectionHeaders; ++i) {
    const char *name = getSectionHeaderName(mSectionHeadersPtr[i].sh_name);
    if (strncmp(name, headerName, strlen(headerName)) == 0) {
      rv = &mSectionHeadersPtr[i];
      break;
    }
  }
  return rv;
}

ElfHeader *NanoappLoader::getElfHeader() {
  return reinterpret_cast<ElfHeader *>(mBinary.data);
}

ProgramHeader *NanoappLoader::getProgramHeaderArray() {
  ElfHeader *elfHeader = getElfHeader();
  ProgramHeader *programHeader = nullptr;
  if (elfHeader != nullptr) {
    programHeader =
        reinterpret_cast<ProgramHeader *>(mBinary.data + elfHeader->e_phoff);
  }

  return programHeader;
}

size_t NanoappLoader::getProgramHeaderArraySize() {
  ElfHeader *elfHeader = getElfHeader();
  size_t arraySize = 0;
  if (elfHeader != nullptr) {
    arraySize = elfHeader->e_phnum;
  }

  return arraySize;
}

char *NanoappLoader::getDynamicStringTable() {
  char *table = nullptr;

  SectionHeader *dynamicStringTablePtr = getSectionHeader(".dynstr");
  CHRE_ASSERT(dynamicStringTablePtr != nullptr);
  if (dynamicStringTablePtr != nullptr && mBinary.dataPtr != nullptr) {
    table = reinterpret_cast<char *>(mBinary.data +
                                     dynamicStringTablePtr->sh_offset);
  }

  return table;
}

uint8_t *NanoappLoader::getDynamicSymbolTable() {
  uint8_t *table = nullptr;

  SectionHeader *dynamicSymbolTablePtr = getSectionHeader(".dynsym");
  CHRE_ASSERT(dynamicSymbolTablePtr != nullptr);
  if (dynamicSymbolTablePtr != nullptr && mBinary.dataPtr != nullptr) {
    table = reinterpret_cast<uint8_t *>(mBinary.data +
                                        dynamicSymbolTablePtr->sh_offset);
  }

  return table;
}

size_t NanoappLoader::getDynamicSymbolTableSize() {
  size_t tableSize = 0;

  SectionHeader *dynamicSymbolTablePtr = getSectionHeader(".dynsym");
  CHRE_ASSERT(dynamicSymbolTablePtr != nullptr);
  if (dynamicSymbolTablePtr != nullptr) {
    tableSize = dynamicSymbolTablePtr->sh_size;
  }

  return tableSize;
}

bool NanoappLoader::verifySectionHeaders() {
  bool foundSymbolTableHeader = false;
  bool foundStringTableHeader = false;

  for (size_t i = 0; i < mNumSectionHeaders; ++i) {
    const char *name = getSectionHeaderName(mSectionHeadersPtr[i].sh_name);

    if (strncmp(name, kSymTableName, strlen(kSymTableName)) == 0) {
      foundSymbolTableHeader = true;
    } else if (strncmp(name, kStrTableName, strlen(kStrTableName)) == 0) {
      foundStringTableHeader = true;
    }
  }

  return foundSymbolTableHeader && foundStringTableHeader;
}

bool NanoappLoader::copyAndVerifyHeaders() {
  size_t offset = 0;
  bool success = false;
  uint8_t *pDataBytes = static_cast<uint8_t *>(mBinary.dataPtr);

  // Verify the ELF Header
  ElfHeader *elfHeader = getElfHeader();
  success = verifyElfHeader();

  LOGV("Verified ELF header %d", success);

  // Verify Program Headers
  if (success) {
    success = verifyProgramHeaders();
  }

  LOGV("Verified Program headers %d", success);

  // Load Section Headers
  if (success) {
    offset = elfHeader->e_shoff;
    size_t sectionHeaderSizeBytes = sizeof(SectionHeader) * elfHeader->e_shnum;
    mSectionHeadersPtr =
        static_cast<SectionHeader *>(memoryAllocDram(sectionHeaderSizeBytes));
    if (mSectionHeadersPtr == nullptr) {
      success = false;
      LOG_OOM();
    } else {
      memcpy(mSectionHeadersPtr, (pDataBytes + offset), sectionHeaderSizeBytes);
      mNumSectionHeaders = elfHeader->e_shnum;
    }
  }

  LOGV("Loaded section headers %d", success);

  // Load section header names
  if (success) {
    SectionHeader &stringSection = mSectionHeadersPtr[elfHeader->e_shstrndx];
    size_t sectionSize = stringSection.sh_size;
    mSectionNamesPtr = static_cast<char *>(memoryAllocDram(sectionSize));
    if (mSectionNamesPtr == nullptr) {
      LOG_OOM();
      success = false;
    } else {
      memcpy(mSectionNamesPtr,
             reinterpret_cast<void *>(mBinary.data + stringSection.sh_offset),
             sectionSize);
    }
  }

  LOGV("Loaded section header names %d", success);

  success = verifySectionHeaders();
  LOGV("Verified Section headers %d", success);

  // Load symbol table
  if (success) {
    SectionHeader *symbolTableHeader = getSectionHeader(kSymTableName);
    mSymbolTableSize = symbolTableHeader->sh_size;
    if (mSymbolTableSize == 0) {
      LOGE("No symbols to resolve");
      success = false;
    } else {
      mSymbolTablePtr =
          static_cast<uint8_t *>(memoryAllocDram(mSymbolTableSize));
      if (mSymbolTablePtr == nullptr) {
        LOG_OOM();
        success = false;
      } else {
        memcpy(mSymbolTablePtr,
               reinterpret_cast<void *>(mBinary.data +
                                        symbolTableHeader->sh_offset),
               mSymbolTableSize);
      }
    }
  }

  LOGV("Loaded symbol table %d", success);

  // Load string table
  if (success) {
    SectionHeader *stringTableHeader = getSectionHeader(kStrTableName);
    size_t stringTableSize = stringTableHeader->sh_size;
    if (mSymbolTableSize == 0) {
      LOGE("No string table corresponding to symbols");
      success = false;
    } else {
      mStringTablePtr = static_cast<char *>(memoryAllocDram(stringTableSize));
      if (mStringTablePtr == nullptr) {
        LOG_OOM();
        success = false;
      } else {
        memcpy(mStringTablePtr,
               reinterpret_cast<void *>(mBinary.data +
                                        stringTableHeader->sh_offset),
               stringTableSize);
      }
    }
  }

  LOGV("Loaded string table %d", success);

  return success;
}

bool NanoappLoader::createMappings() {
  // 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];
  const ProgramHeader *last = &programHeaderArray[numProgramHeaders - 1];

  // Find first load segment
  while (first->p_type != PT_LOAD && first <= last) {
    ++first;
  }

  bool success = false;
  if (first->p_type != PT_LOAD) {
    LOGE("Unable to find any load segments in the binary");
  } else {
    // Verify that the first load segment has a program header
    // 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))));
    if (!valid) {
      LOGE("Load segment program header validation failed");
    } else {
      // Get the last load segment
      while (last > first && last->p_type != PT_LOAD) --last;

      size_t memorySpan = last->p_vaddr + last->p_memsz - first->p_vaddr;
      LOGV("Nanoapp image Memory Span: %u", memorySpan);

      if (mIsTcmBinary) {
        mMapping.dataPtr = memoryAllocAligned(kBinaryAlignment, memorySpan);
      } else {
        mMapping.dataPtr = memoryAllocDramAligned(kBinaryAlignment, memorySpan);
      }

      if (mMapping.dataPtr == nullptr) {
        LOG_OOM();
      } else {
        LOGV("Starting location of mappings %p", mMapping.dataPtr);

        // Calculate the load bias using the first load segment.
        uintptr_t adjustedFirstLoadSegAddr = roundDownToAlign(first->p_vaddr);
        mLoadBias = mMapping.data - adjustedFirstLoadSegAddr;
        LOGV("Load bias is %" PRIu32, mLoadBias);

        success = true;
      }
    }
  }

  if (success) {
    // Map the remaining segments
    for (const ProgramHeader *ph = first; ph <= last; ++ph) {
      if (ph->p_type == PT_LOAD) {
        ElfAddr segStart = ph->p_vaddr + mLoadBias;
        void *startPage = reinterpret_cast<void *>(roundDownToAlign(segStart));
        ElfAddr phOffsetPage = roundDownToAlign(ph->p_offset);
        void *binaryStartPage =
            reinterpret_cast<void *>(mBinary.data + phOffsetPage);
        size_t segmentLen = ph->p_filesz;

        LOGV("Mapping start page %p from %p with length %zu", startPage,
             binaryStartPage, segmentLen);
        memcpy(startPage, binaryStartPage, segmentLen);
        mapBss(ph);
      } else {
        LOGE("Non-load segment found between load segments");
        success = false;
        break;
      }
    }
  }

  return success;
}

const char *NanoappLoader::getDataName(size_t posInSymbolTable) {
  size_t sectionSize = getDynamicSymbolTableSize();
  uint8_t *dynamicSymbolTable = getDynamicSymbolTable();
  size_t numElements = sectionSize / sizeof(ElfSym);
  CHRE_ASSERT(posInSymbolTable < numElements);
  char *dataName = nullptr;
  if (posInSymbolTable < numElements) {
    ElfSym *sym = reinterpret_cast<ElfSym *>(
        &dynamicSymbolTable[posInSymbolTable * sizeof(ElfSym)]);
    dataName = &getDynamicStringTable()[sym->st_name];
  }
  return dataName;
}

void *NanoappLoader::resolveData(size_t posInSymbolTable) {
  const char *dataName = getDataName(posInSymbolTable);

  if (dataName != nullptr) {
    LOGV("Resolving %s", dataName);
    return findExportedSymbol(dataName);
  }

  return nullptr;
}

NanoappLoader::DynamicHeader *NanoappLoader::getDynamicHeader() {
  DynamicHeader *dyn = nullptr;
  ProgramHeader *programHeaders = getProgramHeaderArray();
  for (size_t i = 0; i < getProgramHeaderArraySize(); ++i) {
    if (programHeaders[i].p_type == PT_DYNAMIC) {
      dyn = reinterpret_cast<DynamicHeader *>(programHeaders[i].p_vaddr +
                                              mLoadBias);
      break;
    }
  }
  return dyn;
}

NanoappLoader::ProgramHeader *NanoappLoader::getFirstRoSegHeader() {
  // return the first read only segment found
  ProgramHeader *ro = nullptr;
  ProgramHeader *programHeaders = getProgramHeaderArray();
  for (size_t i = 0; i < getProgramHeaderArraySize(); ++i) {
    if (!(programHeaders[i].p_flags & PF_W)) {
      ro = &programHeaders[i];
      break;
    }
  }
  return ro;
}

NanoappLoader::ElfWord NanoappLoader::getDynEntry(DynamicHeader *dyn,
                                                  int field) {
  ElfWord rv = 0;

  while (dyn->d_tag != DT_NULL) {
    if (dyn->d_tag == field) {
      rv = dyn->d_un.d_val;
      break;
    }
    ++dyn;
  }

  return rv;
}

bool NanoappLoader::fixRelocations() {
  ElfAddr *addr;
  DynamicHeader *dyn = getDynamicHeader();
  ProgramHeader *roSeg = getFirstRoSegHeader();

  bool success = false;
  if ((dyn == nullptr) || (roSeg == nullptr)) {
    LOGE("Mandatory headers missing from shared object, aborting load");
  } else if (getDynEntry(dyn, DT_RELA) != 0) {
    LOGE("Elf binaries with a DT_RELA dynamic entry are unsupported");
  } else {
    ElfRel *reloc =
        reinterpret_cast<ElfRel *>(getDynEntry(dyn, DT_REL) + mBinary.data);
    size_t relocSize = getDynEntry(dyn, DT_RELSZ);
    size_t nRelocs = relocSize / sizeof(ElfRel);
    LOGV("Relocation %zu entries in DT_REL table", nRelocs);

    size_t i;
    for (i = 0; i < nRelocs; ++i) {
      ElfRel *curr = &reloc[i];
      int relocType = ELFW_R_TYPE(curr->r_info);
      switch (relocType) {
        case R_ARM_RELATIVE:
          LOGV("Resolving ARM_RELATIVE at offset %" PRIx32, curr->r_offset);
          addr = reinterpret_cast<ElfAddr *>(curr->r_offset + mMapping.data);
          // TODO: When we move to DRAM allocations, we need to check if the
          // above address is in a Read-Only section of memory, and give it
          // temporary write permission if that is the case.
          *addr += mMapping.data;
          break;

        case R_ARM_ABS32:
        case R_ARM_GLOB_DAT: {
          LOGV("Resolving type %d at offset %" PRIx32, relocType,
               curr->r_offset);
          addr = reinterpret_cast<ElfAddr *>(curr->r_offset + mMapping.data);
          size_t posInSymbolTable = ELFW_R_SYM(curr->r_info);
          void *resolved = resolveData(posInSymbolTable);
          if (resolved == nullptr) {
            LOGV("Failed to resolve global symbol(%d) at offset 0x%x", i,
                 curr->r_offset);
            return false;
          }
          // TODO: When we move to DRAM allocations, we need to check if the
          // above address is in a Read-Only section of memory, and give it
          // temporary write permission if that is the case.
          *addr = reinterpret_cast<ElfAddr>(resolved);
          break;
        }

        case R_ARM_COPY:
          LOGE("R_ARM_COPY is an invalid relocation for shared libraries");
          break;
        default:
          LOGE("Invalid relocation type %u", relocType);
          break;
      }
    }

    if (i != nRelocs) {
      LOGE("Unable to resolve all symbols in the binary");
    } else {
      success = true;
    }
  }

  return success;
}

bool NanoappLoader::resolveGot() {
  ElfAddr *addr;
  ElfRel *reloc = reinterpret_cast<ElfRel *>(
      getDynEntry(getDynamicHeader(), DT_JMPREL) + mMapping.data);
  size_t relocSize = getDynEntry(getDynamicHeader(), DT_PLTRELSZ);
  size_t nRelocs = relocSize / sizeof(ElfRel);
  LOGV("Resolving GOT with %zu relocations", nRelocs);

  for (size_t i = 0; i < nRelocs; ++i) {
    ElfRel *curr = &reloc[i];
    int relocType = ELFW_R_TYPE(curr->r_info);

    switch (relocType) {
      case R_ARM_JUMP_SLOT: {
        LOGV("Resolving ARM_JUMP_SLOT at offset %" PRIx32, curr->r_offset);
        addr = reinterpret_cast<ElfAddr *>(curr->r_offset + mMapping.data);
        size_t posInSymbolTable = ELFW_R_SYM(curr->r_info);
        void *resolved = resolveData(posInSymbolTable);
        if (resolved == nullptr) {
          LOGV("Failed to resolve symbol(%d) at offset 0x%x", i,
               curr->r_offset);
          return false;
        }
        *addr = reinterpret_cast<ElfAddr>(resolved);
        break;
      }

      default:
        LOGE("Unsupported relocation type: %u for symbol %s", relocType,
             getDataName(ELFW_R_SYM(curr->r_info)));
        return false;
    }
  }
  return true;
}

void NanoappLoader::callAtexitFunctions() {
  while (!mAtexitFunctions.empty()) {
    LOGV("Calling atexit at %p", mAtexitFunctions.back());
    mAtexitFunctions.back()();
    mAtexitFunctions.pop_back();
  }
}

void NanoappLoader::callTerminatorArray() {
  for (size_t i = 0; i < mNumSectionHeaders; ++i) {
    const char *name = getSectionHeaderName(mSectionHeadersPtr[i].sh_name);
    if (strncmp(name, kFiniArrayName, strlen(kFiniArrayName)) == 0) {
      uintptr_t finiArray = reinterpret_cast<uintptr_t>(
          mLoadBias + mSectionHeadersPtr[i].sh_addr);
      uintptr_t offset = 0;
      while (offset < mSectionHeadersPtr[i].sh_size) {
        ElfAddr *funcPtr = reinterpret_cast<ElfAddr *>(finiArray + offset);
        uintptr_t finiFunction = reinterpret_cast<uintptr_t>(*funcPtr);
        ((void (*)())finiFunction)();
        offset += sizeof(finiFunction);
      }
      break;
    }
  }
}

}  // namespace chre
