//===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Part of the IRObjectFile class implementation.
//
//===----------------------------------------------------------------------===//

#include "llvm/Object/IRObjectFile.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace object;

IRObjectFile::IRObjectFile(MemoryBufferRef Object,
                           std::vector<std::unique_ptr<Module>> Mods)
    : SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) {
  for (auto &M : this->Mods)
    SymTab.addModule(M.get());
}

IRObjectFile::~IRObjectFile() {}

static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) {
  return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p);
}

void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
  Symb.p += sizeof(ModuleSymbolTable::Symbol);
}

Error IRObjectFile::printSymbolName(raw_ostream &OS, DataRefImpl Symb) const {
  SymTab.printSymbolName(OS, getSym(Symb));
  return Error::success();
}

Expected<uint32_t> IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
  return SymTab.getSymbolFlags(getSym(Symb));
}

basic_symbol_iterator IRObjectFile::symbol_begin() const {
  DataRefImpl Ret;
  Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data());
  return basic_symbol_iterator(BasicSymbolRef(Ret, this));
}

basic_symbol_iterator IRObjectFile::symbol_end() const {
  DataRefImpl Ret;
  Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() +
                                      SymTab.symbols().size());
  return basic_symbol_iterator(BasicSymbolRef(Ret, this));
}

StringRef IRObjectFile::getTargetTriple() const {
  // Each module must have the same target triple, so we arbitrarily access the
  // first one.
  return Mods[0]->getTargetTriple();
}

Expected<MemoryBufferRef>
IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
  for (const SectionRef &Sec : Obj.sections()) {
    if (Sec.isBitcode()) {
      Expected<StringRef> Contents = Sec.getContents();
      if (!Contents)
        return Contents.takeError();
      if (Contents->size() <= 1)
        return errorCodeToError(object_error::bitcode_section_not_found);
      return MemoryBufferRef(*Contents, Obj.getFileName());
    }
  }

  return errorCodeToError(object_error::bitcode_section_not_found);
}

Expected<MemoryBufferRef>
IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
  file_magic Type = identify_magic(Object.getBuffer());
  switch (Type) {
  case file_magic::bitcode:
    return Object;
  case file_magic::elf_relocatable:
  case file_magic::macho_object:
  case file_magic::wasm_object:
  case file_magic::coff_object: {
    Expected<std::unique_ptr<ObjectFile>> ObjFile =
        ObjectFile::createObjectFile(Object, Type);
    if (!ObjFile)
      return ObjFile.takeError();
    return findBitcodeInObject(*ObjFile->get());
  }
  default:
    return errorCodeToError(object_error::invalid_file_type);
  }
}

Expected<std::unique_ptr<IRObjectFile>>
IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) {
  Expected<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
  if (!BCOrErr)
    return BCOrErr.takeError();

  Expected<std::vector<BitcodeModule>> BMsOrErr =
      getBitcodeModuleList(*BCOrErr);
  if (!BMsOrErr)
    return BMsOrErr.takeError();

  std::vector<std::unique_ptr<Module>> Mods;
  for (auto BM : *BMsOrErr) {
    Expected<std::unique_ptr<Module>> MOrErr =
        BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true,
                         /*IsImporting*/ false);
    if (!MOrErr)
      return MOrErr.takeError();

    Mods.push_back(std::move(*MOrErr));
  }

  return std::unique_ptr<IRObjectFile>(
      new IRObjectFile(*BCOrErr, std::move(Mods)));
}

Expected<IRSymtabFile> object::readIRSymtab(MemoryBufferRef MBRef) {
  IRSymtabFile F;
  Expected<MemoryBufferRef> BCOrErr =
      IRObjectFile::findBitcodeInMemBuffer(MBRef);
  if (!BCOrErr)
    return BCOrErr.takeError();

  Expected<BitcodeFileContents> BFCOrErr = getBitcodeFileContents(*BCOrErr);
  if (!BFCOrErr)
    return BFCOrErr.takeError();

  Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BFCOrErr);
  if (!FCOrErr)
    return FCOrErr.takeError();

  F.Mods = std::move(BFCOrErr->Mods);
  F.Symtab = std::move(FCOrErr->Symtab);
  F.Strtab = std::move(FCOrErr->Strtab);
  F.TheReader = std::move(FCOrErr->TheReader);
  return std::move(F);
}
