/*
 * Copyright (C) 2017 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 <elf.h>
#include <stdint.h>

#include <string>

#include "Check.h"
#include "Memory.h"
#include "Symbols.h"

Symbols::Symbols(uint64_t offset, uint64_t size, uint64_t entry_size, uint64_t str_offset,
                 uint64_t str_size)
    : cur_offset_(offset),
      offset_(offset),
      end_(offset + size),
      entry_size_(entry_size),
      str_offset_(str_offset),
      str_end_(str_offset_ + str_size) {}

const Symbols::Info* Symbols::GetInfoFromCache(uint64_t addr) {
  // Binary search the table.
  size_t first = 0;
  size_t last = symbols_.size();
  while (first < last) {
    size_t current = first + (last - first) / 2;
    const Info* info = &symbols_[current];
    if (addr < info->start_offset) {
      last = current;
    } else if (addr < info->end_offset) {
      return info;
    } else {
      first = current + 1;
    }
  }
  return nullptr;
}

template <typename SymType>
bool Symbols::GetName(uint64_t addr, uint64_t load_bias, Memory* elf_memory, std::string* name,
                      uint64_t* func_offset) {
  addr += load_bias;

  if (symbols_.size() != 0) {
    const Info* info = GetInfoFromCache(addr);
    if (info) {
      CHECK(addr >= info->start_offset && addr <= info->end_offset);
      *func_offset = addr - info->start_offset;
      return elf_memory->ReadString(info->str_offset, name, str_end_ - info->str_offset);
    }
  }

  bool symbol_added = false;
  bool return_value = false;
  while (cur_offset_ + entry_size_ <= end_) {
    SymType entry;
    if (!elf_memory->Read(cur_offset_, &entry, sizeof(entry))) {
      // Stop all processing, something looks like it is corrupted.
      cur_offset_ = UINT64_MAX;
      return false;
    }
    cur_offset_ += entry_size_;

    if (entry.st_shndx != SHN_UNDEF && ELF32_ST_TYPE(entry.st_info) == STT_FUNC) {
      // Treat st_value as virtual address.
      uint64_t start_offset = entry.st_value;
      if (entry.st_shndx != SHN_ABS) {
        start_offset += load_bias;
      }
      uint64_t end_offset = start_offset + entry.st_size;

      // Cache the value.
      symbols_.emplace_back(start_offset, end_offset, str_offset_ + entry.st_name);
      symbol_added = true;

      if (addr >= start_offset && addr < end_offset) {
        *func_offset = addr - start_offset;
        uint64_t offset = str_offset_ + entry.st_name;
        if (offset < str_end_) {
          return_value = elf_memory->ReadString(offset, name, str_end_ - offset);
        }
        break;
      }
    }
  }

  if (symbol_added) {
    std::sort(symbols_.begin(), symbols_.end(),
              [](const Info& a, const Info& b) { return a.start_offset < b.start_offset; });
  }
  return return_value;
}

// Instantiate all of the needed template functions.
template bool Symbols::GetName<Elf32_Sym>(uint64_t, uint64_t, Memory*, std::string*, uint64_t*);
template bool Symbols::GetName<Elf64_Sym>(uint64_t, uint64_t, Memory*, std::string*, uint64_t*);
