10f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang/*
20f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * Copyright 2012, The Android Open Source Project
30f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang *
40f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
50f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * you may not use this file except in compliance with the License.
60f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * You may obtain a copy of the License at
70f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang *
80f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
90f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang *
100f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * Unless required by applicable law or agreed to in writing, software
110f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
120f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * See the License for the specific language governing permissions and
140f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * limitations under the License.
150f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang */
160f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
17c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/ExecutionEngine/ObjectLoader.h"
180f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
190f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang#include <utils/FileMap.h>
200f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
21c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/ExecutionEngine/GDBJITRegistrar.h"
22c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Support/FileBase.h"
23ef73a242762bcd8113b9b65ceccbe7d909b5acbcZonr Chang#include "bcc/Support/Log.h"
24c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang
250f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang#include "ELFObjectLoaderImpl.h"
260f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
270f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Changusing namespace bcc;
280f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
290f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr ChangObjectLoader *ObjectLoader::Load(void *pMemStart, size_t pMemSize,
300f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang                                 const char *pName,
310f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang                                 SymbolResolverInterface &pResolver,
320f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang                                 bool pEnableGDBDebug) {
330f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  ObjectLoader *result = NULL;
340f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
350f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // Check parameters.
360f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  if ((pMemStart == NULL) || (pMemSize <= 0)) {
370f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    ALOGE("Invalid memory '%s' was given to load (memory addr: %p, size: %u)",
380f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang          pName, pMemStart, static_cast<unsigned>(pMemSize));
390f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    goto bail;
400f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  }
410f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
420f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // Create result object
430f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  result = new (std::nothrow) ObjectLoader();
440f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  if (result == NULL) {
450f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    ALOGE("Out of memory when create object loader for %s!", pName);
460f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    goto bail;
470f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  }
480f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
490f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // Currently, only ELF object loader is supported. Therefore, there's no codes
500f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // to detect the object file type and to select the one appropriated. Directly
510f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // try out the ELF object loader.
520f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  result->mImpl = new (std::nothrow) ELFObjectLoaderImpl();
530f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  if (result->mImpl == NULL) {
540f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    ALOGE("Out of memory when create ELF object loader for %s", pName);
550f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    goto bail;
560f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  }
570f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
580f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // Load the object file.
590f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  if (!result->mImpl->load(pMemStart, pMemSize)) {
600f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    ALOGE("Failed to load %s!", pName);
610f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    goto bail;
620f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  }
630f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
640f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // Perform relocation.
650f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  if (!result->mImpl->relocate(pResolver)) {
660f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    ALOGE("Error occurred when performs relocation on %s!", pName);
670f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    goto bail;
680f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  }
690f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
700f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // GDB debugging is enabled. Note that error occurrs during the setup of
710f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // debugging won't failed the object load. Only a warning is issued to notify
720f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // that the debugging is disabled due to the failure.
730f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  if (pEnableGDBDebug) {
740f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    // GDB's JIT debugging requires the source object file corresponded to the
750f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    // process image desired to debug with. And some fields in the object file
760f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    // must be updated to record the runtime information after it's loaded into
770f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    // memory. For example, GDB's JIT debugging requires an ELF file with the
780f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    // value of sh_addr in the section header to be the memory address that the
790f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    // section lives in the process image. Therefore, a writable memory with its
800f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    // contents initialized to the contents of pFile is created.
810f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    result->mDebugImage = new (std::nothrow) uint8_t [ pMemSize ];
820f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    if (result->mDebugImage != NULL) {
830f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang      ::memcpy(result->mDebugImage, pMemStart, pMemSize);
840f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang      if (!result->mImpl->prepareDebugImage(result->mDebugImage, pMemSize)) {
850f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang        ALOGW("GDB debug for %s is enabled by the user but won't work due to "
860f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang              "failure debug image preparation!", pName);
870f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang      } else {
880f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang        registerObjectWithGDB(
890f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang            reinterpret_cast<const ObjectBuffer *>(result->mDebugImage),
900f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang            pMemSize);
910f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang      }
920f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    }
930f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  }
940f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
950f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  return result;
960f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
970f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Changbail:
980f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  delete result;
990f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  return NULL;
1000f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang}
1010f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
1020f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr ChangObjectLoader *ObjectLoader::Load(FileBase &pFile,
1030f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang                                 SymbolResolverInterface &pResolver,
1040f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang                                 bool pEnableGDBDebug) {
1050f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  size_t file_size;
1060f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  android::FileMap *file_map = NULL;
1070f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  const char *input_filename = pFile.getName().c_str();
1080f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  ObjectLoader *result = NULL;
1090f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
1100f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // Check the inputs.
1110f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  if (pFile.hasError()) {
1120f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    ALOGE("Input file %s to the object loader is in the invalid state! (%s)",
1130f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang          input_filename, pFile.getErrorMessage().c_str());
1140f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    return NULL;
1150f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  }
1160f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
1170f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // Get the file size.
1180f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  file_size = pFile.getSize();
1190f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  if (pFile.hasError()) {
1200f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    ALOGE("Failed to get size of file %s! (%s)", input_filename,
1210f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang          pFile.getErrorMessage().c_str());
1220f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    return NULL;
1230f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  }
1240f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
1250f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // Abort on empty file.
1260f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  if (file_size <= 0) {
1270f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    ALOGE("Empty file %s to the object loader.", input_filename);
1280f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    return NULL;
1290f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  }
1300f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
1310f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // Create memory map for the input file.
1320f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  file_map = pFile.createMap(0, file_size, /* pIsReadOnly */true);
1330f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  if ((file_map == NULL) || pFile.hasError())  {
1340f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    ALOGE("Failed to map the file %s to the memory! (%s)", input_filename,
1350f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang          pFile.getErrorMessage().c_str());
1360f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang    return NULL;
1370f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  }
1380f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
1390f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // Delegate the load request.
1400f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  result = Load(file_map->getDataPtr(), file_size, input_filename, pResolver,
1410f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang                pEnableGDBDebug);
1420f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
1430f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // No whether the load is successful or not, file_map is no longer needed. On
1440f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // success, there's a copy of the object corresponded to the pFile in the
1450f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  // memory. Therefore, file_map can be safely released.
1460f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  file_map->release();
1470f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
1480f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  return result;
1490f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang}
1500f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
1510f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Changvoid *ObjectLoader::getSymbolAddress(const char *pName) const {
1520f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  return mImpl->getSymbolAddress(pName);
1530f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang}
1540f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang
1559795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liaosize_t ObjectLoader::getSymbolSize(const char *pName) const {
1569795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao  return mImpl->getSymbolSize(pName);
1579795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao}
1589795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao
1599795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liaobool ObjectLoader::getSymbolNameList(android::Vector<const char *>& pNameList,
1609795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao                                     SymbolType pType) const {
1619795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao  return mImpl->getSymbolNameList(pNameList, pType);
1629795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao}
1639795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao
1640f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr ChangObjectLoader::~ObjectLoader() {
1650f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  delete mImpl;
1660f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang  delete [] reinterpret_cast<uint8_t *>(mDebugImage);
1670f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang}
168