//===- bolt/Core/AddressMap.cpp - Input-output Address Map ----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "bolt/Core/AddressMap.h"
#include "bolt/Core/BinaryContext.h"
#include "bolt/Core/BinaryFunction.h"
#include "bolt/Core/BinarySection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/DataExtractor.h"

namespace llvm {
namespace bolt {

const char *const AddressMap::AddressSectionName = ".bolt.addr2addr_map";
const char *const AddressMap::LabelSectionName = ".bolt.label2addr_map";

static void emitAddress(MCStreamer &Streamer, uint64_t InputAddress,
                        const MCSymbol *OutputLabel) {
  Streamer.emitIntValue(InputAddress, 8);
  Streamer.emitSymbolValue(OutputLabel, 8);
}

static void emitLabel(MCStreamer &Streamer, const MCSymbol *OutputLabel) {
  Streamer.emitIntValue(reinterpret_cast<uint64_t>(OutputLabel), 8);
  Streamer.emitSymbolValue(OutputLabel, 8);
}

void AddressMap::emit(MCStreamer &Streamer, BinaryContext &BC) {
  // Mark map sections as link-only to avoid allocation in the output file.
  const unsigned Flags = BinarySection::getFlags(/*IsReadOnly*/ true,
                                                 /*IsText*/ false,
                                                 /*IsAllocatable*/ true);
  BC.registerOrUpdateSection(AddressSectionName, ELF::SHT_PROGBITS, Flags)
      .setLinkOnly();
  BC.registerOrUpdateSection(LabelSectionName, ELF::SHT_PROGBITS, Flags)
      .setLinkOnly();

  for (const auto &[BFAddress, BF] : BC.getBinaryFunctions()) {
    if (!BF.requiresAddressMap())
      continue;

    for (const auto &BB : BF) {
      if (!BB.getLabel()->isDefined())
        continue;

      Streamer.switchSection(BC.getDataSection(LabelSectionName));
      emitLabel(Streamer, BB.getLabel());

      if (!BB.hasLocSyms())
        continue;

      Streamer.switchSection(BC.getDataSection(AddressSectionName));
      for (auto [Offset, Symbol] : BB.getLocSyms())
        emitAddress(Streamer, BFAddress + Offset, Symbol);
    }
  }
}

std::optional<AddressMap> AddressMap::parse(BinaryContext &BC) {
  auto AddressMapSection = BC.getUniqueSectionByName(AddressSectionName);
  auto LabelMapSection = BC.getUniqueSectionByName(LabelSectionName);

  if (!AddressMapSection && !LabelMapSection)
    return std::nullopt;

  AddressMap Parsed;

  unsigned CodePointerSize = BC.AsmInfo->getCodePointerSize();
  const size_t EntrySize = 2 * CodePointerSize;
  auto parseSection =
      [&](BinarySection &Section,
          function_ref<void(uint64_t, uint64_t)> InsertCallback) {
        StringRef Buffer = Section.getOutputContents();
        assert(Buffer.size() % EntrySize == 0 && "Unexpected address map size");

        DataExtractor DE(Buffer, BC.AsmInfo->isLittleEndian());
        DataExtractor::Cursor Cursor(0);

        while (Cursor && !DE.eof(Cursor)) {
          const uint64_t Input = DE.getUnsigned(Cursor, CodePointerSize);
          const uint64_t Output = DE.getUnsigned(Cursor, CodePointerSize);
          InsertCallback(Input, Output);
        }

        assert(Cursor && "Error reading address map section");
        BC.deregisterSection(Section);
      };

  if (AddressMapSection) {
    Parsed.Address2AddressMap.reserve(AddressMapSection->getOutputSize() /
                                      EntrySize);
    parseSection(*AddressMapSection, [&](uint64_t Input, uint64_t Output) {
      if (!Parsed.Address2AddressMap.count(Input))
        Parsed.Address2AddressMap.insert({Input, Output});
    });
  }

  if (LabelMapSection) {
    Parsed.Label2AddrMap.reserve(LabelMapSection->getOutputSize() / EntrySize);
    parseSection(*LabelMapSection, [&](uint64_t Input, uint64_t Output) {
      assert(!Parsed.Label2AddrMap.count(
                 reinterpret_cast<const MCSymbol *>(Input)) &&
             "Duplicate label entry detected.");
      Parsed.Label2AddrMap.insert(
          {reinterpret_cast<const MCSymbol *>(Input), Output});
    });
  }

  return Parsed;
}

} // namespace bolt
} // namespace llvm
