//===- MachOUniversalWriter.cpp - MachO universal binary writer---*- 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
//
//===----------------------------------------------------------------------===//
//
// Defines the Slice class and writeUniversalBinary function for writing a MachO
// universal binary file.
//
//===----------------------------------------------------------------------===//

#include "llvm/Object/MachOUniversalWriter.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBufferRef.h"
#include "llvm/Support/SwapByteOrder.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"

using namespace llvm;
using namespace object;

// For compatibility with cctools lipo, a file's alignment is calculated as the
// minimum aligment of all segments. For object files, the file's alignment is
// the maximum alignment of its sections.
static uint32_t calculateFileAlignment(const MachOObjectFile &O) {
  uint32_t P2CurrentAlignment;
  uint32_t P2MinAlignment = MachOUniversalBinary::MaxSectionAlignment;
  const bool Is64Bit = O.is64Bit();

  for (const auto &LC : O.load_commands()) {
    if (LC.C.cmd != (Is64Bit ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT))
      continue;
    if (O.getHeader().filetype == MachO::MH_OBJECT) {
      unsigned NumberOfSections =
          (Is64Bit ? O.getSegment64LoadCommand(LC).nsects
                   : O.getSegmentLoadCommand(LC).nsects);
      P2CurrentAlignment = NumberOfSections ? 2 : P2MinAlignment;
      for (unsigned SI = 0; SI < NumberOfSections; ++SI) {
        P2CurrentAlignment = std::max(P2CurrentAlignment,
                                      (Is64Bit ? O.getSection64(LC, SI).align
                                               : O.getSection(LC, SI).align));
      }
    } else {
      P2CurrentAlignment =
          llvm::countr_zero(Is64Bit ? O.getSegment64LoadCommand(LC).vmaddr
                                    : O.getSegmentLoadCommand(LC).vmaddr);
    }
    P2MinAlignment = std::min(P2MinAlignment, P2CurrentAlignment);
  }
  // return a value >= 4 byte aligned, and less than MachO MaxSectionAlignment
  return std::max(
      static_cast<uint32_t>(2),
      std::min(P2MinAlignment, static_cast<uint32_t>(
                                   MachOUniversalBinary::MaxSectionAlignment)));
}

static uint32_t calculateAlignment(const MachOObjectFile &ObjectFile) {
  switch (ObjectFile.getHeader().cputype) {
  case MachO::CPU_TYPE_I386:
  case MachO::CPU_TYPE_X86_64:
  case MachO::CPU_TYPE_POWERPC:
  case MachO::CPU_TYPE_POWERPC64:
    return 12; // log2 value of page size(4k) for x86 and PPC
  case MachO::CPU_TYPE_ARM:
  case MachO::CPU_TYPE_ARM64:
  case MachO::CPU_TYPE_ARM64_32:
    return 14; // log2 value of page size(16k) for Darwin ARM
  default:
    return calculateFileAlignment(ObjectFile);
  }
}

Slice::Slice(const Archive &A, uint32_t CPUType, uint32_t CPUSubType,
             std::string ArchName, uint32_t Align)
    : B(&A), CPUType(CPUType), CPUSubType(CPUSubType),
      ArchName(std::move(ArchName)), P2Alignment(Align) {}

Slice::Slice(const MachOObjectFile &O, uint32_t Align)
    : B(&O), CPUType(O.getHeader().cputype),
      CPUSubType(O.getHeader().cpusubtype),
      ArchName(std::string(O.getArchTriple().getArchName())),
      P2Alignment(Align) {}

Slice::Slice(const IRObjectFile &IRO, uint32_t CPUType, uint32_t CPUSubType,
             std::string ArchName, uint32_t Align)
    : B(&IRO), CPUType(CPUType), CPUSubType(CPUSubType),
      ArchName(std::move(ArchName)), P2Alignment(Align) {}

Slice::Slice(const MachOObjectFile &O) : Slice(O, calculateAlignment(O)) {}

using MachoCPUTy = std::pair<unsigned, unsigned>;

static Expected<MachoCPUTy> getMachoCPUFromTriple(Triple TT) {
  auto CPU = std::make_pair(MachO::getCPUType(TT), MachO::getCPUSubType(TT));
  if (!CPU.first) {
    return CPU.first.takeError();
  }
  if (!CPU.second) {
    return CPU.second.takeError();
  }
  return std::make_pair(*CPU.first, *CPU.second);
}

static Expected<MachoCPUTy> getMachoCPUFromTriple(StringRef TT) {
  return getMachoCPUFromTriple(Triple{TT});
}

Expected<Slice> Slice::create(const Archive &A, LLVMContext *LLVMCtx) {
  Error Err = Error::success();
  std::unique_ptr<MachOObjectFile> MFO = nullptr;
  std::unique_ptr<IRObjectFile> IRFO = nullptr;
  for (const Archive::Child &Child : A.children(Err)) {
    Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary(LLVMCtx);
    if (!ChildOrErr)
      return createFileError(A.getFileName(), ChildOrErr.takeError());
    Binary *Bin = ChildOrErr.get().get();
    if (Bin->isMachOUniversalBinary())
      return createStringError(std::errc::invalid_argument,
                               ("archive member " + Bin->getFileName() +
                                " is a fat file (not allowed in an archive)")
                                   .str()
                                   .c_str());
    if (Bin->isMachO()) {
      MachOObjectFile *O = cast<MachOObjectFile>(Bin);
      if (IRFO) {
        return createStringError(
            std::errc::invalid_argument,
            "archive member %s is a MachO, while previous archive member "
            "%s was an IR LLVM object",
            O->getFileName().str().c_str(), IRFO->getFileName().str().c_str());
      }
      if (MFO &&
          std::tie(MFO->getHeader().cputype, MFO->getHeader().cpusubtype) !=
              std::tie(O->getHeader().cputype, O->getHeader().cpusubtype)) {
        return createStringError(
            std::errc::invalid_argument,
            ("archive member " + O->getFileName() + " cputype (" +
             Twine(O->getHeader().cputype) + ") and cpusubtype(" +
             Twine(O->getHeader().cpusubtype) +
             ") does not match previous archive members cputype (" +
             Twine(MFO->getHeader().cputype) + ") and cpusubtype(" +
             Twine(MFO->getHeader().cpusubtype) +
             ") (all members must match) " + MFO->getFileName())
                .str()
                .c_str());
      }
      if (!MFO) {
        ChildOrErr.get().release();
        MFO.reset(O);
      }
    } else if (Bin->isIR()) {
      IRObjectFile *O = cast<IRObjectFile>(Bin);
      if (MFO) {
        return createStringError(std::errc::invalid_argument,
                                 "archive member '%s' is an LLVM IR object, "
                                 "while previous archive member "
                                 "'%s' was a MachO",
                                 O->getFileName().str().c_str(),
                                 MFO->getFileName().str().c_str());
      }
      if (IRFO) {
        Expected<MachoCPUTy> CPUO = getMachoCPUFromTriple(O->getTargetTriple());
        Expected<MachoCPUTy> CPUFO =
            getMachoCPUFromTriple(IRFO->getTargetTriple());
        if (!CPUO)
          return CPUO.takeError();
        if (!CPUFO)
          return CPUFO.takeError();
        if (*CPUO != *CPUFO) {
          return createStringError(
              std::errc::invalid_argument,
              ("archive member " + O->getFileName() + " cputype (" +
               Twine(CPUO->first) + ") and cpusubtype(" + Twine(CPUO->second) +
               ") does not match previous archive members cputype (" +
               Twine(CPUFO->first) + ") and cpusubtype(" +
               Twine(CPUFO->second) + ") (all members must match) " +
               IRFO->getFileName())
                  .str()
                  .c_str());
        }
      } else {
        ChildOrErr.get().release();
        IRFO.reset(O);
      }
    } else
      return createStringError(std::errc::invalid_argument,
                               ("archive member " + Bin->getFileName() +
                                " is neither a MachO file or an LLVM IR file "
                                "(not allowed in an archive)")
                                   .str()
                                   .c_str());
  }
  if (Err)
    return createFileError(A.getFileName(), std::move(Err));
  if (!MFO && !IRFO)
    return createStringError(
        std::errc::invalid_argument,
        ("empty archive with no architecture specification: " +
         A.getFileName() + " (can't determine architecture for it)")
            .str()
            .c_str());

  if (MFO) {
    Slice ArchiveSlice(*(MFO), MFO->is64Bit() ? 3 : 2);
    ArchiveSlice.B = &A;
    return ArchiveSlice;
  }

  // For IR objects
  Expected<Slice> ArchiveSliceOrErr = Slice::create(*IRFO, 0);
  if (!ArchiveSliceOrErr)
    return createFileError(A.getFileName(), ArchiveSliceOrErr.takeError());
  auto &ArchiveSlice = ArchiveSliceOrErr.get();
  ArchiveSlice.B = &A;
  return std::move(ArchiveSlice);
}

Expected<Slice> Slice::create(const IRObjectFile &IRO, uint32_t Align) {
  Expected<MachoCPUTy> CPUOrErr = getMachoCPUFromTriple(IRO.getTargetTriple());
  if (!CPUOrErr)
    return CPUOrErr.takeError();
  unsigned CPUType, CPUSubType;
  std::tie(CPUType, CPUSubType) = CPUOrErr.get();
  // We don't directly use the architecture name of the target triple T, as,
  // for instance, thumb is treated as ARM by the MachOUniversal object.
  std::string ArchName(
      MachOObjectFile::getArchTriple(CPUType, CPUSubType).getArchName());
  return Slice{IRO, CPUType, CPUSubType, std::move(ArchName), Align};
}

static Expected<SmallVector<MachO::fat_arch, 2>>
buildFatArchList(ArrayRef<Slice> Slices) {
  SmallVector<MachO::fat_arch, 2> FatArchList;
  uint64_t Offset =
      sizeof(MachO::fat_header) + Slices.size() * sizeof(MachO::fat_arch);

  for (const auto &S : Slices) {
    Offset = alignTo(Offset, 1ull << S.getP2Alignment());
    if (Offset > UINT32_MAX)
      return createStringError(
          std::errc::invalid_argument,
          ("fat file too large to be created because the offset "
           "field in struct fat_arch is only 32-bits and the offset " +
           Twine(Offset) + " for " + S.getBinary()->getFileName() +
           " for architecture " + S.getArchString() + "exceeds that.")
              .str()
              .c_str());

    MachO::fat_arch FatArch;
    FatArch.cputype = S.getCPUType();
    FatArch.cpusubtype = S.getCPUSubType();
    FatArch.offset = Offset;
    FatArch.size = S.getBinary()->getMemoryBufferRef().getBufferSize();
    FatArch.align = S.getP2Alignment();
    Offset += FatArch.size;
    FatArchList.push_back(FatArch);
  }
  return FatArchList;
}

Error object::writeUniversalBinaryToStream(ArrayRef<Slice> Slices,
                                           raw_ostream &Out) {
  MachO::fat_header FatHeader;
  FatHeader.magic = MachO::FAT_MAGIC;
  FatHeader.nfat_arch = Slices.size();

  Expected<SmallVector<MachO::fat_arch, 2>> FatArchListOrErr =
      buildFatArchList(Slices);
  if (!FatArchListOrErr)
    return FatArchListOrErr.takeError();
  SmallVector<MachO::fat_arch, 2> FatArchList = *FatArchListOrErr;

  if (sys::IsLittleEndianHost)
    MachO::swapStruct(FatHeader);
  Out.write(reinterpret_cast<const char *>(&FatHeader),
            sizeof(MachO::fat_header));

  if (sys::IsLittleEndianHost)
    for (MachO::fat_arch &FA : FatArchList)
      MachO::swapStruct(FA);
  Out.write(reinterpret_cast<const char *>(FatArchList.data()),
            sizeof(MachO::fat_arch) * FatArchList.size());

  if (sys::IsLittleEndianHost)
    for (MachO::fat_arch &FA : FatArchList)
      MachO::swapStruct(FA);

  size_t Offset =
      sizeof(MachO::fat_header) + sizeof(MachO::fat_arch) * FatArchList.size();
  for (size_t Index = 0, Size = Slices.size(); Index < Size; ++Index) {
    MemoryBufferRef BufferRef = Slices[Index].getBinary()->getMemoryBufferRef();
    assert((Offset <= FatArchList[Index].offset) && "Incorrect slice offset");
    Out.write_zeros(FatArchList[Index].offset - Offset);
    Out.write(BufferRef.getBufferStart(), BufferRef.getBufferSize());
    Offset = FatArchList[Index].offset + BufferRef.getBufferSize();
  }

  Out.flush();
  return Error::success();
}

Error object::writeUniversalBinary(ArrayRef<Slice> Slices,
                                   StringRef OutputFileName) {
  const bool IsExecutable = any_of(Slices, [](Slice S) {
    return sys::fs::can_execute(S.getBinary()->getFileName());
  });
  unsigned Mode = sys::fs::all_read | sys::fs::all_write;
  if (IsExecutable)
    Mode |= sys::fs::all_exe;
  Expected<sys::fs::TempFile> Temp = sys::fs::TempFile::create(
      OutputFileName + ".temp-universal-%%%%%%", Mode);
  if (!Temp)
    return Temp.takeError();
  raw_fd_ostream Out(Temp->FD, false);
  if (Error E = writeUniversalBinaryToStream(Slices, Out)) {
    if (Error DiscardError = Temp->discard())
      return joinErrors(std::move(E), std::move(DiscardError));
    return E;
  }
  return Temp->keep(OutputFileName);
}
