/*
 * 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, kElfSegmentAlignment);
  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
