//===-- llvm-jitlink-macho.cpp -- MachO parsing support for llvm-jitlink --===//
//
// 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 "llvm-jitlink.h"

#include "llvm/Support/Error.h"
#include "llvm/Support/Path.h"

#define DEBUG_TYPE "llvm-jitlink"

using namespace llvm;
using namespace llvm::jitlink;

static bool isMachOGOTSection(Section &S) { return S.getName() == "$__GOT"; }

static bool isMachOStubsSection(Section &S) {
  return S.getName() == "$__STUBS";
}

static Expected<Edge &> getFirstRelocationEdge(AtomGraph &G, DefinedAtom &DA) {
  auto EItr = std::find_if(DA.edges().begin(), DA.edges().end(),
                           [](Edge &E) { return E.isRelocation(); });
  if (EItr == DA.edges().end())
    return make_error<StringError>("GOT entry in " + G.getName() + ", \"" +
                                       DA.getSection().getName() +
                                       "\" has no relocations",
                                   inconvertibleErrorCode());
  return *EItr;
}

static Expected<Atom &> getMachOGOTTarget(AtomGraph &G, DefinedAtom &DA) {
  auto E = getFirstRelocationEdge(G, DA);
  if (!E)
    return E.takeError();
  auto &TA = E->getTarget();
  if (!TA.hasName())
    return make_error<StringError>("GOT entry in " + G.getName() + ", \"" +
                                       DA.getSection().getName() +
                                       "\" points to anonymous "
                                       "atom",
                                   inconvertibleErrorCode());
  if (TA.isDefined() || TA.isAbsolute())
    return make_error<StringError>(
        "GOT entry \"" + TA.getName() + "\" in " + G.getName() + ", \"" +
            DA.getSection().getName() + "\" does not point to an external atom",
        inconvertibleErrorCode());
  return TA;
}

static Expected<Atom &> getMachOStubTarget(AtomGraph &G, DefinedAtom &DA) {
  auto E = getFirstRelocationEdge(G, DA);
  if (!E)
    return E.takeError();
  auto &GOTA = E->getTarget();
  if (!GOTA.isDefined() ||
      !isMachOGOTSection(static_cast<DefinedAtom &>(GOTA).getSection()))
    return make_error<StringError>("Stubs entry in " + G.getName() + ", \"" +
                                       DA.getSection().getName() +
                                       "\" does not point to GOT entry",
                                   inconvertibleErrorCode());
  return getMachOGOTTarget(G, static_cast<DefinedAtom &>(GOTA));
}

namespace llvm {

Error registerMachOStubsAndGOT(Session &S, AtomGraph &G) {
  auto FileName = sys::path::filename(G.getName());
  if (S.FileInfos.count(FileName)) {
    return make_error<StringError>("When -check is passed, file names must be "
                                   "distinct (duplicate: \"" +
                                       FileName + "\")",
                                   inconvertibleErrorCode());
  }

  auto &FileInfo = S.FileInfos[FileName];
  LLVM_DEBUG({
    dbgs() << "Registering MachO file info for \"" << FileName << "\"\n";
  });
  for (auto &Sec : G.sections()) {
    LLVM_DEBUG({
      dbgs() << "  Section \"" << Sec.getName() << "\": "
             << (Sec.atoms_empty() ? "empty. skipping." : "processing...")
             << "\n";
    });

    // Skip empty sections.
    if (Sec.atoms_empty())
      continue;

    if (FileInfo.SectionInfos.count(Sec.getName()))
      return make_error<StringError>("Encountered duplicate section name \"" +
                                         Sec.getName() + "\" in \"" + FileName +
                                         "\"",
                                     inconvertibleErrorCode());

    bool isGOTSection = isMachOGOTSection(Sec);
    bool isStubsSection = isMachOStubsSection(Sec);

    auto &SectionInfo = FileInfo.SectionInfos[Sec.getName()];

    auto *FirstAtom = *Sec.atoms().begin();
    auto *LastAtom = FirstAtom;
    for (auto *DA : Sec.atoms()) {
      if (DA->getAddress() < FirstAtom->getAddress())
        FirstAtom = DA;
      if (DA->getAddress() > LastAtom->getAddress())
        LastAtom = DA;
      if (isGOTSection) {
        if (auto TA = getMachOGOTTarget(G, *DA)) {
          FileInfo.GOTEntryInfos[TA->getName()] = {DA->getContent(),
                                                   DA->getAddress()};
        } else
          return TA.takeError();
      } else if (isStubsSection) {
        if (auto TA = getMachOStubTarget(G, *DA))
          FileInfo.StubInfos[TA->getName()] = {DA->getContent(),
                                               DA->getAddress()};
        else
          return TA.takeError();
      } else if (DA->hasName() && DA->isGlobal())
        S.SymbolInfos[DA->getName()] = {DA->getContent(), DA->getAddress()};
    }
    const char *StartAddr = FirstAtom->getContent().data();
    const char *EndAddr =
        LastAtom->getContent().data() + LastAtom->getContent().size();
    SectionInfo.TargetAddress = FirstAtom->getAddress();
    SectionInfo.Content = StringRef(StartAddr, EndAddr - StartAddr);
  }

  return Error::success();
}

} // end namespace llvm
