/*
 * Copyright (C) 2016 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 "multi_oat_relative_patcher.h"

#include <android-base/logging.h>

#include "base/bit_utils.h"
#include "base/globals.h"
#include "driver/compiled_method_storage.h"

namespace art {
namespace linker {

void MultiOatRelativePatcher::ThunkProvider::GetThunkCode(const LinkerPatch& patch,
                                                          /*out*/ ArrayRef<const uint8_t>* code,
                                                          /*out*/ std::string* debug_name) {
  *code = storage_->GetThunkCode(patch, debug_name);
  DCHECK(!code->empty());
}


MultiOatRelativePatcher::MultiOatRelativePatcher(InstructionSet instruction_set,
                                                 const InstructionSetFeatures* features,
                                                 CompiledMethodStorage* storage)
    : thunk_provider_(storage),
      method_offset_map_(),
      relative_patcher_(RelativePatcher::Create(instruction_set,
                                                features,
                                                &thunk_provider_,
                                                &method_offset_map_)),
      adjustment_(0u),
      instruction_set_(instruction_set),
      start_size_code_alignment_(0u),
      start_size_relative_call_thunks_(0u),
      start_size_misc_thunks_(0u) {
}

void MultiOatRelativePatcher::StartOatFile(uint32_t adjustment) {
  DCHECK_ALIGNED(adjustment, kPageSize);
  adjustment_ = adjustment;

  start_size_code_alignment_ = relative_patcher_->CodeAlignmentSize();
  start_size_relative_call_thunks_ = relative_patcher_->RelativeCallThunksSize();
  start_size_misc_thunks_ = relative_patcher_->MiscThunksSize();
}

uint32_t MultiOatRelativePatcher::CodeAlignmentSize() const {
  DCHECK_GE(relative_patcher_->CodeAlignmentSize(), start_size_code_alignment_);
  return relative_patcher_->CodeAlignmentSize() - start_size_code_alignment_;
}

uint32_t MultiOatRelativePatcher::RelativeCallThunksSize() const {
  DCHECK_GE(relative_patcher_->RelativeCallThunksSize(), start_size_relative_call_thunks_);
  return relative_patcher_->RelativeCallThunksSize() - start_size_relative_call_thunks_;
}

uint32_t MultiOatRelativePatcher::MiscThunksSize() const {
  DCHECK_GE(relative_patcher_->MiscThunksSize(), start_size_misc_thunks_);
  return relative_patcher_->MiscThunksSize() - start_size_misc_thunks_;
}

std::pair<bool, uint32_t> MultiOatRelativePatcher::MethodOffsetMap::FindMethodOffset(
    MethodReference ref) {
  auto it = map.find(ref);
  if (it == map.end()) {
    return std::pair<bool, uint32_t>(false, 0u);
  } else {
    return std::pair<bool, uint32_t>(true, it->second);
  }
}
}  // namespace linker
}  // namespace art
