Exemplo n.º 1
0
bool ElfReader::Load() {
  return ReadElfHeader() &&
         VerifyElfHeader() &&
         ReadProgramHeader() &&
         ReserveAddressSpace() &&
         LoadSegments() &&
         FindPhdr();
}
bool ElfLoader::LoadAt(const char* lib_path,
                       off_t file_offset,
                       uintptr_t wanted_address,
                       Error* error) {

  LOG("%s: lib_path='%s', file_offset=%p, load_address=%p\n",
      __FUNCTION__,
      lib_path,
      file_offset,
      wanted_address);

  // Check that the load address is properly page-aligned.
  if (wanted_address != PAGE_START(wanted_address)) {
    error->Format("Load address is not page aligned (%08x)", wanted_address);
    return false;
  }
  wanted_load_address_ = reinterpret_cast<void*>(wanted_address);

  // Check that the file offset is also properly page-aligned.
  // PAGE_START() can't be used here due to the compiler complaining about
  // comparing signed (off_t) and unsigned (size_t) values.
  if ((file_offset & static_cast<off_t>(PAGE_SIZE - 1)) != 0) {
    error->Format("File offset is not page aligned (%08x)", file_offset);
    return false;
  }
  file_offset_ = file_offset;

  // Open the file.
  if (!fd_.OpenReadOnly(lib_path)) {
    error->Format("Can't open file: %s", strerror(errno));
    return false;
  }

  if (file_offset && fd_.SeekTo(file_offset) < 0) {
    error->Format(
        "Can't seek to file offset %08x: %s", file_offset, strerror(errno));
    return false;
  }

  path_ = lib_path;

  if (!ReadElfHeader(error) || !ReadProgramHeader(error) ||
      !ReserveAddressSpace(error)) {
    return false;
  }

  if (!LoadSegments(error) || !FindPhdr(error)) {
    // An error occured, cleanup the address space by un-mapping the
    // range that was reserved by ReserveAddressSpace().
    if (load_start_ && load_size_)
      munmap(load_start_, load_size_);

    return false;
  }

  return true;
}