//===- ArchiveWriter.cpp - ar File Format 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
//
//===----------------------------------------------------------------------===//
//
// This file defines the writeArchive function.
//
//===----------------------------------------------------------------------===//

#include "llvm/Object/ArchiveWriter.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/Error.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Object/XCOFFObjectFile.h"
#include "llvm/Support/Alignment.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SmallVectorMemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"

#include <cerrno>
#include <map>

#if !defined(_MSC_VER) && !defined(__MINGW32__)
#include <unistd.h>
#else
#include <io.h>
#endif

using namespace llvm;
using namespace llvm::object;

struct SymMap {
  bool UseECMap;
  std::map<std::string, uint16_t> Map;
  std::map<std::string, uint16_t> ECMap;
};

NewArchiveMember::NewArchiveMember(MemoryBufferRef BufRef)
    : Buf(MemoryBuffer::getMemBuffer(BufRef, false)),
      MemberName(BufRef.getBufferIdentifier()) {}

object::Archive::Kind NewArchiveMember::detectKindFromObject() const {
  auto MemBufferRef = this->Buf->getMemBufferRef();
  Expected<std::unique_ptr<object::ObjectFile>> OptionalObject =
      object::ObjectFile::createObjectFile(MemBufferRef);

  if (OptionalObject)
    return isa<object::MachOObjectFile>(**OptionalObject)
               ? object::Archive::K_DARWIN
               : (isa<object::XCOFFObjectFile>(**OptionalObject)
                      ? object::Archive::K_AIXBIG
                      : object::Archive::K_GNU);

  // Squelch the error in case we had a non-object file.
  consumeError(OptionalObject.takeError());

  // If we're adding a bitcode file to the archive, detect the Archive kind
  // based on the target triple.
  LLVMContext Context;
  if (identify_magic(MemBufferRef.getBuffer()) == file_magic::bitcode) {
    if (auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
            MemBufferRef, file_magic::bitcode, &Context)) {
      auto &IRObject = cast<object::IRObjectFile>(**ObjOrErr);
      auto TargetTriple = Triple(IRObject.getTargetTriple());
      return TargetTriple.isOSDarwin()
                 ? object::Archive::K_DARWIN
                 : (TargetTriple.isOSAIX() ? object::Archive::K_AIXBIG
                                           : object::Archive::K_GNU);
    } else {
      // Squelch the error in case this was not a SymbolicFile.
      consumeError(ObjOrErr.takeError());
    }
  }

  return object::Archive::getDefaultKindForHost();
}

Expected<NewArchiveMember>
NewArchiveMember::getOldMember(const object::Archive::Child &OldMember,
                               bool Deterministic) {
  Expected<llvm::MemoryBufferRef> BufOrErr = OldMember.getMemoryBufferRef();
  if (!BufOrErr)
    return BufOrErr.takeError();

  NewArchiveMember M;
  M.Buf = MemoryBuffer::getMemBuffer(*BufOrErr, false);
  M.MemberName = M.Buf->getBufferIdentifier();
  if (!Deterministic) {
    auto ModTimeOrErr = OldMember.getLastModified();
    if (!ModTimeOrErr)
      return ModTimeOrErr.takeError();
    M.ModTime = ModTimeOrErr.get();
    Expected<unsigned> UIDOrErr = OldMember.getUID();
    if (!UIDOrErr)
      return UIDOrErr.takeError();
    M.UID = UIDOrErr.get();
    Expected<unsigned> GIDOrErr = OldMember.getGID();
    if (!GIDOrErr)
      return GIDOrErr.takeError();
    M.GID = GIDOrErr.get();
    Expected<sys::fs::perms> AccessModeOrErr = OldMember.getAccessMode();
    if (!AccessModeOrErr)
      return AccessModeOrErr.takeError();
    M.Perms = AccessModeOrErr.get();
  }
  return std::move(M);
}

Expected<NewArchiveMember> NewArchiveMember::getFile(StringRef FileName,
                                                     bool Deterministic) {
  sys::fs::file_status Status;
  auto FDOrErr = sys::fs::openNativeFileForRead(FileName);
  if (!FDOrErr)
    return FDOrErr.takeError();
  sys::fs::file_t FD = *FDOrErr;
  assert(FD != sys::fs::kInvalidFile);

  if (auto EC = sys::fs::status(FD, Status))
    return errorCodeToError(EC);

  // Opening a directory doesn't make sense. Let it fail.
  // Linux cannot open directories with open(2), although
  // cygwin and *bsd can.
  if (Status.type() == sys::fs::file_type::directory_file)
    return errorCodeToError(make_error_code(errc::is_a_directory));

  ErrorOr<std::unique_ptr<MemoryBuffer>> MemberBufferOrErr =
      MemoryBuffer::getOpenFile(FD, FileName, Status.getSize(), false);
  if (!MemberBufferOrErr)
    return errorCodeToError(MemberBufferOrErr.getError());

  if (auto EC = sys::fs::closeFile(FD))
    return errorCodeToError(EC);

  NewArchiveMember M;
  M.Buf = std::move(*MemberBufferOrErr);
  M.MemberName = M.Buf->getBufferIdentifier();
  if (!Deterministic) {
    M.ModTime = std::chrono::time_point_cast<std::chrono::seconds>(
        Status.getLastModificationTime());
    M.UID = Status.getUser();
    M.GID = Status.getGroup();
    M.Perms = Status.permissions();
  }
  return std::move(M);
}

template <typename T>
static void printWithSpacePadding(raw_ostream &OS, T Data, unsigned Size) {
  uint64_t OldPos = OS.tell();
  OS << Data;
  unsigned SizeSoFar = OS.tell() - OldPos;
  assert(SizeSoFar <= Size && "Data doesn't fit in Size");
  OS.indent(Size - SizeSoFar);
}

static bool isDarwin(object::Archive::Kind Kind) {
  return Kind == object::Archive::K_DARWIN ||
         Kind == object::Archive::K_DARWIN64;
}

static bool isAIXBigArchive(object::Archive::Kind Kind) {
  return Kind == object::Archive::K_AIXBIG;
}

static bool isCOFFArchive(object::Archive::Kind Kind) {
  return Kind == object::Archive::K_COFF;
}

static bool isBSDLike(object::Archive::Kind Kind) {
  switch (Kind) {
  case object::Archive::K_GNU:
  case object::Archive::K_GNU64:
  case object::Archive::K_AIXBIG:
  case object::Archive::K_COFF:
    return false;
  case object::Archive::K_BSD:
  case object::Archive::K_DARWIN:
  case object::Archive::K_DARWIN64:
    return true;
  }
  llvm_unreachable("not supported for writting");
}

template <class T>
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val) {
  support::endian::write(Out, Val,
                         isBSDLike(Kind) ? llvm::endianness::little
                                         : llvm::endianness::big);
}

template <class T> static void printLE(raw_ostream &Out, T Val) {
  support::endian::write(Out, Val, llvm::endianness::little);
}

static void printRestOfMemberHeader(
    raw_ostream &Out, const sys::TimePoint<std::chrono::seconds> &ModTime,
    unsigned UID, unsigned GID, unsigned Perms, uint64_t Size) {
  printWithSpacePadding(Out, sys::toTimeT(ModTime), 12);

  // The format has only 6 chars for uid and gid. Truncate if the provided
  // values don't fit.
  printWithSpacePadding(Out, UID % 1000000, 6);
  printWithSpacePadding(Out, GID % 1000000, 6);

  printWithSpacePadding(Out, format("%o", Perms), 8);
  printWithSpacePadding(Out, Size, 10);
  Out << "`\n";
}

static void
printGNUSmallMemberHeader(raw_ostream &Out, StringRef Name,
                          const sys::TimePoint<std::chrono::seconds> &ModTime,
                          unsigned UID, unsigned GID, unsigned Perms,
                          uint64_t Size) {
  printWithSpacePadding(Out, Twine(Name) + "/", 16);
  printRestOfMemberHeader(Out, ModTime, UID, GID, Perms, Size);
}

static void
printBSDMemberHeader(raw_ostream &Out, uint64_t Pos, StringRef Name,
                     const sys::TimePoint<std::chrono::seconds> &ModTime,
                     unsigned UID, unsigned GID, unsigned Perms, uint64_t Size) {
  uint64_t PosAfterHeader = Pos + 60 + Name.size();
  // Pad so that even 64 bit object files are aligned.
  unsigned Pad = offsetToAlignment(PosAfterHeader, Align(8));
  unsigned NameWithPadding = Name.size() + Pad;
  printWithSpacePadding(Out, Twine("#1/") + Twine(NameWithPadding), 16);
  printRestOfMemberHeader(Out, ModTime, UID, GID, Perms,
                          NameWithPadding + Size);
  Out << Name;
  while (Pad--)
    Out.write(uint8_t(0));
}

static void
printBigArchiveMemberHeader(raw_ostream &Out, StringRef Name,
                            const sys::TimePoint<std::chrono::seconds> &ModTime,
                            unsigned UID, unsigned GID, unsigned Perms,
                            uint64_t Size, uint64_t PrevOffset,
                            uint64_t NextOffset) {
  unsigned NameLen = Name.size();

  printWithSpacePadding(Out, Size, 20);           // File member size
  printWithSpacePadding(Out, NextOffset, 20);     // Next member header offset
  printWithSpacePadding(Out, PrevOffset, 20); // Previous member header offset
  printWithSpacePadding(Out, sys::toTimeT(ModTime), 12); // File member date
  // The big archive format has 12 chars for uid and gid.
  printWithSpacePadding(Out, UID % 1000000000000, 12);   // UID
  printWithSpacePadding(Out, GID % 1000000000000, 12);   // GID
  printWithSpacePadding(Out, format("%o", Perms), 12);   // Permission
  printWithSpacePadding(Out, NameLen, 4);                // Name length
  if (NameLen) {
    printWithSpacePadding(Out, Name, NameLen); // Name
    if (NameLen % 2)
      Out.write(uint8_t(0)); // Null byte padding
  }
  Out << "`\n"; // Terminator
}

static bool useStringTable(bool Thin, StringRef Name) {
  return Thin || Name.size() >= 16 || Name.contains('/');
}

static bool is64BitKind(object::Archive::Kind Kind) {
  switch (Kind) {
  case object::Archive::K_GNU:
  case object::Archive::K_BSD:
  case object::Archive::K_DARWIN:
  case object::Archive::K_COFF:
    return false;
  case object::Archive::K_AIXBIG:
  case object::Archive::K_DARWIN64:
  case object::Archive::K_GNU64:
    return true;
  }
  llvm_unreachable("not supported for writting");
}

static void
printMemberHeader(raw_ostream &Out, uint64_t Pos, raw_ostream &StringTable,
                  StringMap<uint64_t> &MemberNames, object::Archive::Kind Kind,
                  bool Thin, const NewArchiveMember &M,
                  sys::TimePoint<std::chrono::seconds> ModTime, uint64_t Size) {
  if (isBSDLike(Kind))
    return printBSDMemberHeader(Out, Pos, M.MemberName, ModTime, M.UID, M.GID,
                                M.Perms, Size);
  if (!useStringTable(Thin, M.MemberName))
    return printGNUSmallMemberHeader(Out, M.MemberName, ModTime, M.UID, M.GID,
                                     M.Perms, Size);
  Out << '/';
  uint64_t NamePos;
  if (Thin) {
    NamePos = StringTable.tell();
    StringTable << M.MemberName << "/\n";
  } else {
    auto Insertion = MemberNames.insert({M.MemberName, uint64_t(0)});
    if (Insertion.second) {
      Insertion.first->second = StringTable.tell();
      StringTable << M.MemberName;
      if (isCOFFArchive(Kind))
        StringTable << '\0';
      else
        StringTable << "/\n";
    }
    NamePos = Insertion.first->second;
  }
  printWithSpacePadding(Out, NamePos, 15);
  printRestOfMemberHeader(Out, ModTime, M.UID, M.GID, M.Perms, Size);
}

namespace {
struct MemberData {
  std::vector<unsigned> Symbols;
  std::string Header;
  StringRef Data;
  StringRef Padding;
  uint64_t PreHeadPadSize = 0;
  std::unique_ptr<SymbolicFile> SymFile = nullptr;
};
} // namespace

static MemberData computeStringTable(StringRef Names) {
  unsigned Size = Names.size();
  unsigned Pad = offsetToAlignment(Size, Align(2));
  std::string Header;
  raw_string_ostream Out(Header);
  printWithSpacePadding(Out, "//", 48);
  printWithSpacePadding(Out, Size + Pad, 10);
  Out << "`\n";
  Out.flush();
  return {{}, std::move(Header), Names, Pad ? "\n" : ""};
}

static sys::TimePoint<std::chrono::seconds> now(bool Deterministic) {
  using namespace std::chrono;

  if (!Deterministic)
    return time_point_cast<seconds>(system_clock::now());
  return sys::TimePoint<seconds>();
}

static bool isArchiveSymbol(const object::BasicSymbolRef &S) {
  Expected<uint32_t> SymFlagsOrErr = S.getFlags();
  if (!SymFlagsOrErr)
    // TODO: Actually report errors helpfully.
    report_fatal_error(SymFlagsOrErr.takeError());
  if (*SymFlagsOrErr & object::SymbolRef::SF_FormatSpecific)
    return false;
  if (!(*SymFlagsOrErr & object::SymbolRef::SF_Global))
    return false;
  if (*SymFlagsOrErr & object::SymbolRef::SF_Undefined)
    return false;
  return true;
}

static void printNBits(raw_ostream &Out, object::Archive::Kind Kind,
                       uint64_t Val) {
  if (is64BitKind(Kind))
    print<uint64_t>(Out, Kind, Val);
  else
    print<uint32_t>(Out, Kind, Val);
}

static uint64_t computeSymbolTableSize(object::Archive::Kind Kind,
                                       uint64_t NumSyms, uint64_t OffsetSize,
                                       uint64_t StringTableSize,
                                       uint32_t *Padding = nullptr) {
  assert((OffsetSize == 4 || OffsetSize == 8) && "Unsupported OffsetSize");
  uint64_t Size = OffsetSize; // Number of entries
  if (isBSDLike(Kind))
    Size += NumSyms * OffsetSize * 2; // Table
  else
    Size += NumSyms * OffsetSize; // Table
  if (isBSDLike(Kind))
    Size += OffsetSize; // byte count
  Size += StringTableSize;
  // ld64 expects the members to be 8-byte aligned for 64-bit content and at
  // least 4-byte aligned for 32-bit content.  Opt for the larger encoding
  // uniformly.
  // We do this for all bsd formats because it simplifies aligning members.
  // For the big archive format, the symbol table is the last member, so there
  // is no need to align.
  uint32_t Pad = isAIXBigArchive(Kind)
                     ? 0
                     : offsetToAlignment(Size, Align(isBSDLike(Kind) ? 8 : 2));

  Size += Pad;
  if (Padding)
    *Padding = Pad;
  return Size;
}

static uint64_t computeSymbolMapSize(uint64_t NumObj, SymMap &SymMap,
                                     uint32_t *Padding = nullptr) {
  uint64_t Size = sizeof(uint32_t) * 2; // Number of symbols and objects entries
  Size += NumObj * sizeof(uint32_t);    // Offset table

  for (auto S : SymMap.Map)
    Size += sizeof(uint16_t) + S.first.length() + 1;

  uint32_t Pad = offsetToAlignment(Size, Align(2));
  Size += Pad;
  if (Padding)
    *Padding = Pad;
  return Size;
}

static uint64_t computeECSymbolsSize(SymMap &SymMap,
                                     uint32_t *Padding = nullptr) {
  uint64_t Size = sizeof(uint32_t); // Number of symbols

  for (auto S : SymMap.ECMap)
    Size += sizeof(uint16_t) + S.first.length() + 1;

  uint32_t Pad = offsetToAlignment(Size, Align(2));
  Size += Pad;
  if (Padding)
    *Padding = Pad;
  return Size;
}

static void writeSymbolTableHeader(raw_ostream &Out, object::Archive::Kind Kind,
                                   bool Deterministic, uint64_t Size,
                                   uint64_t PrevMemberOffset = 0,
                                   uint64_t NextMemberOffset = 0) {
  if (isBSDLike(Kind)) {
    const char *Name = is64BitKind(Kind) ? "__.SYMDEF_64" : "__.SYMDEF";
    printBSDMemberHeader(Out, Out.tell(), Name, now(Deterministic), 0, 0, 0,
                         Size);
  } else if (isAIXBigArchive(Kind)) {
    printBigArchiveMemberHeader(Out, "", now(Deterministic), 0, 0, 0, Size,
                                PrevMemberOffset, NextMemberOffset);
  } else {
    const char *Name = is64BitKind(Kind) ? "/SYM64" : "";
    printGNUSmallMemberHeader(Out, Name, now(Deterministic), 0, 0, 0, Size);
  }
}

static uint64_t computeHeadersSize(object::Archive::Kind Kind,
                                   uint64_t NumMembers,
                                   uint64_t StringMemberSize, uint64_t NumSyms,
                                   uint64_t SymNamesSize, SymMap *SymMap) {
  uint32_t OffsetSize = is64BitKind(Kind) ? 8 : 4;
  uint64_t SymtabSize =
      computeSymbolTableSize(Kind, NumSyms, OffsetSize, SymNamesSize);
  auto computeSymbolTableHeaderSize = [=] {
    SmallString<0> TmpBuf;
    raw_svector_ostream Tmp(TmpBuf);
    writeSymbolTableHeader(Tmp, Kind, true, SymtabSize);
    return TmpBuf.size();
  };
  uint32_t HeaderSize = computeSymbolTableHeaderSize();
  uint64_t Size = strlen("!<arch>\n") + HeaderSize + SymtabSize;

  if (SymMap) {
    Size += HeaderSize + computeSymbolMapSize(NumMembers, *SymMap);
    if (SymMap->ECMap.size())
      Size += HeaderSize + computeECSymbolsSize(*SymMap);
  }

  return Size + StringMemberSize;
}

static Expected<std::unique_ptr<SymbolicFile>>
getSymbolicFile(MemoryBufferRef Buf, LLVMContext &Context) {
  const file_magic Type = identify_magic(Buf.getBuffer());
  // Don't attempt to read non-symbolic file types.
  if (!object::SymbolicFile::isSymbolicFile(Type, &Context))
    return nullptr;
  if (Type == file_magic::bitcode) {
    auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
        Buf, file_magic::bitcode, &Context);
    if (!ObjOrErr)
      return ObjOrErr.takeError();
    return std::move(*ObjOrErr);
  } else {
    auto ObjOrErr = object::SymbolicFile::createSymbolicFile(Buf);
    if (!ObjOrErr)
      return ObjOrErr.takeError();
    return std::move(*ObjOrErr);
  }
}

static bool is64BitSymbolicFile(const SymbolicFile *SymObj) {
  return SymObj != nullptr ? SymObj->is64Bit() : false;
}

// Log2 of PAGESIZE(4096) on an AIX system.
static const uint32_t Log2OfAIXPageSize = 12;

// In the AIX big archive format, since the data content follows the member file
// name, if the name ends on an odd byte, an extra byte will be added for
// padding. This ensures that the data within the member file starts at an even
// byte.
static const uint32_t MinBigArchiveMemDataAlign = 2;

template <typename AuxiliaryHeader>
uint16_t getAuxMaxAlignment(uint16_t AuxHeaderSize, AuxiliaryHeader *AuxHeader,
                            uint16_t Log2OfMaxAlign) {
  // If the member doesn't have an auxiliary header, it isn't a loadable object
  // and so it just needs aligning at the minimum value.
  if (AuxHeader == nullptr)
    return MinBigArchiveMemDataAlign;

  // If the auxiliary header does not have both MaxAlignOfData and
  // MaxAlignOfText field, it is not a loadable shared object file, so align at
  // the minimum value. The 'ModuleType' member is located right after
  // 'MaxAlignOfData' in the AuxiliaryHeader.
  if (AuxHeaderSize < offsetof(AuxiliaryHeader, ModuleType))
    return MinBigArchiveMemDataAlign;

  // If the XCOFF object file does not have a loader section, it is not
  // loadable, so align at the minimum value.
  if (AuxHeader->SecNumOfLoader == 0)
    return MinBigArchiveMemDataAlign;

  // The content of the loadable member file needs to be aligned at MAX(maximum
  // alignment of .text, maximum alignment of .data) if there are both fields.
  // If the desired alignment is > PAGESIZE, 32-bit members are aligned on a
  // word boundary, while 64-bit members are aligned on a PAGESIZE(2^12=4096)
  // boundary.
  uint16_t Log2OfAlign =
      std::max(AuxHeader->MaxAlignOfText, AuxHeader->MaxAlignOfData);
  return 1 << (Log2OfAlign > Log2OfAIXPageSize ? Log2OfMaxAlign : Log2OfAlign);
}

// AIX big archives may contain shared object members. The AIX OS requires these
// members to be aligned if they are 64-bit and recommends it for 32-bit
// members. This ensures that when these members are loaded they are aligned in
// memory.
static uint32_t getMemberAlignment(SymbolicFile *SymObj) {
  XCOFFObjectFile *XCOFFObj = dyn_cast_or_null<XCOFFObjectFile>(SymObj);
  if (!XCOFFObj)
    return MinBigArchiveMemDataAlign;

  // If the desired alignment is > PAGESIZE, 32-bit members are aligned on a
  // word boundary, while 64-bit members are aligned on a PAGESIZE boundary.
  return XCOFFObj->is64Bit()
             ? getAuxMaxAlignment(XCOFFObj->fileHeader64()->AuxHeaderSize,
                                  XCOFFObj->auxiliaryHeader64(),
                                  Log2OfAIXPageSize)
             : getAuxMaxAlignment(XCOFFObj->fileHeader32()->AuxHeaderSize,
                                  XCOFFObj->auxiliaryHeader32(), 2);
}

static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind,
                             bool Deterministic, ArrayRef<MemberData> Members,
                             StringRef StringTable, uint64_t MembersOffset,
                             unsigned NumSyms, uint64_t PrevMemberOffset = 0,
                             uint64_t NextMemberOffset = 0,
                             bool Is64Bit = false) {
  // We don't write a symbol table on an archive with no members -- except on
  // Darwin, where the linker will abort unless the archive has a symbol table.
  if (StringTable.empty() && !isDarwin(Kind) && !isCOFFArchive(Kind))
    return;

  uint64_t OffsetSize = is64BitKind(Kind) ? 8 : 4;
  uint32_t Pad;
  uint64_t Size = computeSymbolTableSize(Kind, NumSyms, OffsetSize,
                                         StringTable.size(), &Pad);
  writeSymbolTableHeader(Out, Kind, Deterministic, Size, PrevMemberOffset,
                         NextMemberOffset);

  if (isBSDLike(Kind))
    printNBits(Out, Kind, NumSyms * 2 * OffsetSize);
  else
    printNBits(Out, Kind, NumSyms);

  uint64_t Pos = MembersOffset;
  for (const MemberData &M : Members) {
    if (isAIXBigArchive(Kind)) {
      Pos += M.PreHeadPadSize;
      if (is64BitSymbolicFile(M.SymFile.get()) != Is64Bit) {
        Pos += M.Header.size() + M.Data.size() + M.Padding.size();
        continue;
      }
    }

    for (unsigned StringOffset : M.Symbols) {
      if (isBSDLike(Kind))
        printNBits(Out, Kind, StringOffset);
      printNBits(Out, Kind, Pos); // member offset
    }
    Pos += M.Header.size() + M.Data.size() + M.Padding.size();
  }

  if (isBSDLike(Kind))
    // byte count of the string table
    printNBits(Out, Kind, StringTable.size());
  Out << StringTable;

  while (Pad--)
    Out.write(uint8_t(0));
}

static void writeSymbolMap(raw_ostream &Out, object::Archive::Kind Kind,
                           bool Deterministic, ArrayRef<MemberData> Members,
                           SymMap &SymMap, uint64_t MembersOffset) {
  uint32_t Pad;
  uint64_t Size = computeSymbolMapSize(Members.size(), SymMap, &Pad);
  writeSymbolTableHeader(Out, Kind, Deterministic, Size, 0);

  uint32_t Pos = MembersOffset;

  printLE<uint32_t>(Out, Members.size());
  for (const MemberData &M : Members) {
    printLE(Out, Pos); // member offset
    Pos += M.Header.size() + M.Data.size() + M.Padding.size();
  }

  printLE<uint32_t>(Out, SymMap.Map.size());

  for (auto S : SymMap.Map)
    printLE(Out, S.second);
  for (auto S : SymMap.Map)
    Out << S.first << '\0';

  while (Pad--)
    Out.write(uint8_t(0));
}

static void writeECSymbols(raw_ostream &Out, object::Archive::Kind Kind,
                           bool Deterministic, ArrayRef<MemberData> Members,
                           SymMap &SymMap) {
  uint32_t Pad;
  uint64_t Size = computeECSymbolsSize(SymMap, &Pad);
  printGNUSmallMemberHeader(Out, "/<ECSYMBOLS>", now(Deterministic), 0, 0, 0,
                            Size);

  printLE<uint32_t>(Out, SymMap.ECMap.size());

  for (auto S : SymMap.ECMap)
    printLE(Out, S.second);
  for (auto S : SymMap.ECMap)
    Out << S.first << '\0';
  while (Pad--)
    Out.write(uint8_t(0));
}

static bool isECObject(object::SymbolicFile &Obj) {
  if (Obj.isCOFF())
    return cast<llvm::object::COFFObjectFile>(&Obj)->getMachine() !=
           COFF::IMAGE_FILE_MACHINE_ARM64;

  if (Obj.isCOFFImportFile())
    return cast<llvm::object::COFFImportFile>(&Obj)->getMachine() !=
           COFF::IMAGE_FILE_MACHINE_ARM64;

  if (Obj.isIR()) {
    Expected<std::string> TripleStr =
        getBitcodeTargetTriple(Obj.getMemoryBufferRef());
    if (!TripleStr)
      return false;
    Triple T(*TripleStr);
    return T.isWindowsArm64EC() || T.getArch() == Triple::x86_64;
  }

  return false;
}

bool isImportDescriptor(StringRef Name) {
  return Name.starts_with(ImportDescriptorPrefix) ||
         Name == StringRef{NullImportDescriptorSymbolName} ||
         (Name.starts_with(NullThunkDataPrefix) &&
          Name.ends_with(NullThunkDataSuffix));
}

static Expected<std::vector<unsigned>> getSymbols(SymbolicFile *Obj,
                                                  uint16_t Index,
                                                  raw_ostream &SymNames,
                                                  SymMap *SymMap) {
  std::vector<unsigned> Ret;

  if (Obj == nullptr)
    return Ret;

  std::map<std::string, uint16_t> *Map = nullptr;
  if (SymMap)
    Map = SymMap->UseECMap && isECObject(*Obj) ? &SymMap->ECMap : &SymMap->Map;

  for (const object::BasicSymbolRef &S : Obj->symbols()) {
    if (!isArchiveSymbol(S))
      continue;
    if (Map) {
      std::string Name;
      raw_string_ostream NameStream(Name);
      if (Error E = S.printName(NameStream))
        return std::move(E);
      if (Map->find(Name) != Map->end())
        continue; // ignore duplicated symbol
      (*Map)[Name] = Index;
      if (Map == &SymMap->Map) {
        Ret.push_back(SymNames.tell());
        SymNames << Name << '\0';
        // If EC is enabled, then the import descriptors are NOT put into EC
        // objects so we need to copy them to the EC map manually.
        if (SymMap->UseECMap && isImportDescriptor(Name))
          SymMap->ECMap[Name] = Index;
      }
    } else {
      Ret.push_back(SymNames.tell());
      if (Error E = S.printName(SymNames))
        return std::move(E);
      SymNames << '\0';
    }
  }
  return Ret;
}

static Expected<std::vector<MemberData>>
computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
                  object::Archive::Kind Kind, bool Thin, bool Deterministic,
                  SymtabWritingMode NeedSymbols, SymMap *SymMap,
                  LLVMContext &Context, ArrayRef<NewArchiveMember> NewMembers) {
  static char PaddingData[8] = {'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'};
  uint64_t MemHeadPadSize = 0;
  uint64_t Pos =
      isAIXBigArchive(Kind) ? sizeof(object::BigArchive::FixLenHdr) : 0;

  std::vector<MemberData> Ret;
  bool HasObject = false;

  // Deduplicate long member names in the string table and reuse earlier name
  // offsets. This especially saves space for COFF Import libraries where all
  // members have the same name.
  StringMap<uint64_t> MemberNames;

  // UniqueTimestamps is a special case to improve debugging on Darwin:
  //
  // The Darwin linker does not link debug info into the final
  // binary. Instead, it emits entries of type N_OSO in the output
  // binary's symbol table, containing references to the linked-in
  // object files. Using that reference, the debugger can read the
  // debug data directly from the object files. Alternatively, an
  // invocation of 'dsymutil' will link the debug data from the object
  // files into a dSYM bundle, which can be loaded by the debugger,
  // instead of the object files.
  //
  // For an object file, the N_OSO entries contain the absolute path
  // path to the file, and the file's timestamp. For an object
  // included in an archive, the path is formatted like
  // "/absolute/path/to/archive.a(member.o)", and the timestamp is the
  // archive member's timestamp, rather than the archive's timestamp.
  //
  // However, this doesn't always uniquely identify an object within
  // an archive -- an archive file can have multiple entries with the
  // same filename. (This will happen commonly if the original object
  // files started in different directories.) The only way they get
  // distinguished, then, is via the timestamp. But this process is
  // unable to find the correct object file in the archive when there
  // are two files of the same name and timestamp.
  //
  // Additionally, timestamp==0 is treated specially, and causes the
  // timestamp to be ignored as a match criteria.
  //
  // That will "usually" work out okay when creating an archive not in
  // deterministic timestamp mode, because the objects will probably
  // have been created at different timestamps.
  //
  // To ameliorate this problem, in deterministic archive mode (which
  // is the default), on Darwin we will emit a unique non-zero
  // timestamp for each entry with a duplicated name. This is still
  // deterministic: the only thing affecting that timestamp is the
  // order of the files in the resultant archive.
  //
  // See also the functions that handle the lookup:
  // in lldb: ObjectContainerBSDArchive::Archive::FindObject()
  // in llvm/tools/dsymutil: BinaryHolder::GetArchiveMemberBuffers().
  bool UniqueTimestamps = Deterministic && isDarwin(Kind);
  std::map<StringRef, unsigned> FilenameCount;
  if (UniqueTimestamps) {
    for (const NewArchiveMember &M : NewMembers)
      FilenameCount[M.MemberName]++;
    for (auto &Entry : FilenameCount)
      Entry.second = Entry.second > 1 ? 1 : 0;
  }

  // The big archive format needs to know the offset of the previous member
  // header.
  uint64_t PrevOffset = 0;
  uint64_t NextMemHeadPadSize = 0;
  std::unique_ptr<SymbolicFile> CurSymFile;
  std::unique_ptr<SymbolicFile> NextSymFile;
  uint16_t Index = 0;

  for (auto M = NewMembers.begin(); M < NewMembers.end(); ++M) {
    std::string Header;
    raw_string_ostream Out(Header);

    MemoryBufferRef Buf = M->Buf->getMemBufferRef();
    StringRef Data = Thin ? "" : Buf.getBuffer();

    Index++;

    // ld64 expects the members to be 8-byte aligned for 64-bit content and at
    // least 4-byte aligned for 32-bit content.  Opt for the larger encoding
    // uniformly.  This matches the behaviour with cctools and ensures that ld64
    // is happy with archives that we generate.
    unsigned MemberPadding =
        isDarwin(Kind) ? offsetToAlignment(Data.size(), Align(8)) : 0;
    unsigned TailPadding =
        offsetToAlignment(Data.size() + MemberPadding, Align(2));
    StringRef Padding = StringRef(PaddingData, MemberPadding + TailPadding);

    sys::TimePoint<std::chrono::seconds> ModTime;
    if (UniqueTimestamps)
      // Increment timestamp for each file of a given name.
      ModTime = sys::toTimePoint(FilenameCount[M->MemberName]++);
    else
      ModTime = M->ModTime;

    uint64_t Size = Buf.getBufferSize() + MemberPadding;
    if (Size > object::Archive::MaxMemberSize) {
      std::string StringMsg =
          "File " + M->MemberName.str() + " exceeds size limit";
      return make_error<object::GenericBinaryError>(
          std::move(StringMsg), object::object_error::parse_failed);
    }

    if (NeedSymbols != SymtabWritingMode::NoSymtab || isAIXBigArchive(Kind)) {
      auto SetNextSymFile = [&NextSymFile,
                             &Context](MemoryBufferRef Buf,
                                       StringRef MemberName) -> Error {
        Expected<std::unique_ptr<SymbolicFile>> SymFileOrErr =
            getSymbolicFile(Buf, Context);
        if (!SymFileOrErr)
          return createFileError(MemberName, SymFileOrErr.takeError());
        NextSymFile = std::move(*SymFileOrErr);
        return Error::success();
      };

      if (M == NewMembers.begin())
        if (Error Err = SetNextSymFile(Buf, M->MemberName))
          return std::move(Err);

      CurSymFile = std::move(NextSymFile);

      if ((M + 1) != NewMembers.end())
        if (Error Err = SetNextSymFile((M + 1)->Buf->getMemBufferRef(),
                                       (M + 1)->MemberName))
          return std::move(Err);
    }

    // In the big archive file format, we need to calculate and include the next
    // member offset and previous member offset in the file member header.
    if (isAIXBigArchive(Kind)) {
      uint64_t OffsetToMemData = Pos + sizeof(object::BigArMemHdrType) +
                                 alignTo(M->MemberName.size(), 2);

      if (M == NewMembers.begin())
        NextMemHeadPadSize =
            alignToPowerOf2(OffsetToMemData,
                            getMemberAlignment(CurSymFile.get())) -
            OffsetToMemData;

      MemHeadPadSize = NextMemHeadPadSize;
      Pos += MemHeadPadSize;
      uint64_t NextOffset = Pos + sizeof(object::BigArMemHdrType) +
                            alignTo(M->MemberName.size(), 2) + alignTo(Size, 2);

      // If there is another member file after this, we need to calculate the
      // padding before the header.
      if ((M + 1) != NewMembers.end()) {
        uint64_t OffsetToNextMemData = NextOffset +
                                       sizeof(object::BigArMemHdrType) +
                                       alignTo((M + 1)->MemberName.size(), 2);
        NextMemHeadPadSize =
            alignToPowerOf2(OffsetToNextMemData,
                            getMemberAlignment(NextSymFile.get())) -
            OffsetToNextMemData;
        NextOffset += NextMemHeadPadSize;
      }
      printBigArchiveMemberHeader(Out, M->MemberName, ModTime, M->UID, M->GID,
                                  M->Perms, Size, PrevOffset, NextOffset);
      PrevOffset = Pos;
    } else {
      printMemberHeader(Out, Pos, StringTable, MemberNames, Kind, Thin, *M,
                        ModTime, Size);
    }
    Out.flush();

    std::vector<unsigned> Symbols;
    if (NeedSymbols != SymtabWritingMode::NoSymtab) {
      Expected<std::vector<unsigned>> SymbolsOrErr =
          getSymbols(CurSymFile.get(), Index, SymNames, SymMap);
      if (!SymbolsOrErr)
        return createFileError(M->MemberName, SymbolsOrErr.takeError());
      Symbols = std::move(*SymbolsOrErr);
      if (CurSymFile)
        HasObject = true;
    }

    Pos += Header.size() + Data.size() + Padding.size();
    Ret.push_back({std::move(Symbols), std::move(Header), Data, Padding,
                   MemHeadPadSize, std::move(CurSymFile)});
  }
  // If there are no symbols, emit an empty symbol table, to satisfy Solaris
  // tools, older versions of which expect a symbol table in a non-empty
  // archive, regardless of whether there are any symbols in it.
  if (HasObject && SymNames.tell() == 0 && !isCOFFArchive(Kind))
    SymNames << '\0' << '\0' << '\0';
  return std::move(Ret);
}

namespace llvm {

static ErrorOr<SmallString<128>> canonicalizePath(StringRef P) {
  SmallString<128> Ret = P;
  std::error_code Err = sys::fs::make_absolute(Ret);
  if (Err)
    return Err;
  sys::path::remove_dots(Ret, /*removedotdot*/ true);
  return Ret;
}

// Compute the relative path from From to To.
Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To) {
  ErrorOr<SmallString<128>> PathToOrErr = canonicalizePath(To);
  ErrorOr<SmallString<128>> DirFromOrErr = canonicalizePath(From);
  if (!PathToOrErr || !DirFromOrErr)
    return errorCodeToError(std::error_code(errno, std::generic_category()));

  const SmallString<128> &PathTo = *PathToOrErr;
  const SmallString<128> &DirFrom = sys::path::parent_path(*DirFromOrErr);

  // Can't construct a relative path between different roots
  if (sys::path::root_name(PathTo) != sys::path::root_name(DirFrom))
    return sys::path::convert_to_slash(PathTo);

  // Skip common prefixes
  auto FromTo =
      std::mismatch(sys::path::begin(DirFrom), sys::path::end(DirFrom),
                    sys::path::begin(PathTo));
  auto FromI = FromTo.first;
  auto ToI = FromTo.second;

  // Construct relative path
  SmallString<128> Relative;
  for (auto FromE = sys::path::end(DirFrom); FromI != FromE; ++FromI)
    sys::path::append(Relative, sys::path::Style::posix, "..");

  for (auto ToE = sys::path::end(PathTo); ToI != ToE; ++ToI)
    sys::path::append(Relative, sys::path::Style::posix, *ToI);

  return std::string(Relative);
}

static Error writeArchiveToStream(raw_ostream &Out,
                                  ArrayRef<NewArchiveMember> NewMembers,
                                  SymtabWritingMode WriteSymtab,
                                  object::Archive::Kind Kind,
                                  bool Deterministic, bool Thin, bool IsEC) {
  assert((!Thin || !isBSDLike(Kind)) && "Only the gnu format has a thin mode");

  SmallString<0> SymNamesBuf;
  raw_svector_ostream SymNames(SymNamesBuf);
  SmallString<0> StringTableBuf;
  raw_svector_ostream StringTable(StringTableBuf);
  SymMap SymMap;

  // COFF symbol map uses 16-bit indexes, so we can't use it if there are too
  // many members.
  if (isCOFFArchive(Kind) && NewMembers.size() > 0xfffe)
    Kind = object::Archive::K_GNU;

  // In the scenario when LLVMContext is populated SymbolicFile will contain a
  // reference to it, thus SymbolicFile should be destroyed first.
  LLVMContext Context;

  SymMap.UseECMap = IsEC;
  Expected<std::vector<MemberData>> DataOrErr = computeMemberData(
      StringTable, SymNames, Kind, Thin, Deterministic, WriteSymtab,
      isCOFFArchive(Kind) ? &SymMap : nullptr, Context, NewMembers);
  if (Error E = DataOrErr.takeError())
    return E;
  std::vector<MemberData> &Data = *DataOrErr;

  uint64_t StringTableSize = 0;
  MemberData StringTableMember;
  if (!StringTableBuf.empty() && !isAIXBigArchive(Kind)) {
    StringTableMember = computeStringTable(StringTableBuf);
    StringTableSize = StringTableMember.Header.size() +
                      StringTableMember.Data.size() +
                      StringTableMember.Padding.size();
  }

  // We would like to detect if we need to switch to a 64-bit symbol table.
  uint64_t LastMemberEndOffset = 0;
  uint64_t LastMemberHeaderOffset = 0;
  uint64_t NumSyms = 0;
  uint64_t NumSyms32 = 0; // Store symbol number of 32-bit member files.
  bool ShouldWriteSymtab = WriteSymtab != SymtabWritingMode::NoSymtab;

  for (const auto &M : Data) {
    // Record the start of the member's offset
    LastMemberEndOffset += M.PreHeadPadSize;
    LastMemberHeaderOffset = LastMemberEndOffset;
    // Account for the size of each part associated with the member.
    LastMemberEndOffset += M.Header.size() + M.Data.size() + M.Padding.size();
    NumSyms += M.Symbols.size();

    // AIX big archive files may contain two global symbol tables. The
    // first global symbol table locates 32-bit file members that define global
    // symbols; the second global symbol table does the same for 64-bit file
    // members. As a big archive can have both 32-bit and 64-bit file members,
    // we need to know the number of symbols in each symbol table individually.
    if (isAIXBigArchive(Kind) && ShouldWriteSymtab) {
        if (!is64BitSymbolicFile(M.SymFile.get()))
          NumSyms32 += M.Symbols.size();
      }
  }

  std::optional<uint64_t> HeadersSize;

  // The symbol table is put at the end of the big archive file. The symbol
  // table is at the start of the archive file for other archive formats.
  if (ShouldWriteSymtab && !is64BitKind(Kind)) {
    // We assume 32-bit offsets to see if 32-bit symbols are possible or not.
    HeadersSize = computeHeadersSize(Kind, Data.size(), StringTableSize,
                                     NumSyms, SymNamesBuf.size(),
                                     isCOFFArchive(Kind) ? &SymMap : nullptr);

    // The SYM64 format is used when an archive's member offsets are larger than
    // 32-bits can hold. The need for this shift in format is detected by
    // writeArchive. To test this we need to generate a file with a member that
    // has an offset larger than 32-bits but this demands a very slow test. To
    // speed the test up we use this environment variable to pretend like the
    // cutoff happens before 32-bits and instead happens at some much smaller
    // value.
    uint64_t Sym64Threshold = 1ULL << 32;
    const char *Sym64Env = std::getenv("SYM64_THRESHOLD");
    if (Sym64Env)
      StringRef(Sym64Env).getAsInteger(10, Sym64Threshold);

    // If LastMemberHeaderOffset isn't going to fit in a 32-bit varible we need
    // to switch to 64-bit. Note that the file can be larger than 4GB as long as
    // the last member starts before the 4GB offset.
    if (*HeadersSize + LastMemberHeaderOffset >= Sym64Threshold) {
      if (Kind == object::Archive::K_DARWIN)
        Kind = object::Archive::K_DARWIN64;
      else
        Kind = object::Archive::K_GNU64;
      HeadersSize.reset();
    }
  }

  if (Thin)
    Out << "!<thin>\n";
  else if (isAIXBigArchive(Kind))
    Out << "<bigaf>\n";
  else
    Out << "!<arch>\n";

  if (!isAIXBigArchive(Kind)) {
    if (ShouldWriteSymtab) {
      if (!HeadersSize)
        HeadersSize = computeHeadersSize(
            Kind, Data.size(), StringTableSize, NumSyms, SymNamesBuf.size(),
            isCOFFArchive(Kind) ? &SymMap : nullptr);
      writeSymbolTable(Out, Kind, Deterministic, Data, SymNamesBuf,
                       *HeadersSize, NumSyms);

      if (isCOFFArchive(Kind))
        writeSymbolMap(Out, Kind, Deterministic, Data, SymMap, *HeadersSize);
    }

    if (StringTableSize)
      Out << StringTableMember.Header << StringTableMember.Data
          << StringTableMember.Padding;

    if (ShouldWriteSymtab && SymMap.ECMap.size())
      writeECSymbols(Out, Kind, Deterministic, Data, SymMap);

    for (const MemberData &M : Data)
      Out << M.Header << M.Data << M.Padding;
  } else {
    HeadersSize = sizeof(object::BigArchive::FixLenHdr);
    LastMemberEndOffset += *HeadersSize;
    LastMemberHeaderOffset += *HeadersSize;

    // For the big archive (AIX) format, compute a table of member names and
    // offsets, used in the member table.
    uint64_t MemberTableNameStrTblSize = 0;
    std::vector<size_t> MemberOffsets;
    std::vector<StringRef> MemberNames;
    // Loop across object to find offset and names.
    uint64_t MemberEndOffset = sizeof(object::BigArchive::FixLenHdr);
    for (size_t I = 0, Size = NewMembers.size(); I != Size; ++I) {
      const NewArchiveMember &Member = NewMembers[I];
      MemberTableNameStrTblSize += Member.MemberName.size() + 1;
      MemberEndOffset += Data[I].PreHeadPadSize;
      MemberOffsets.push_back(MemberEndOffset);
      MemberNames.push_back(Member.MemberName);
      // File member name ended with "`\n". The length is included in
      // BigArMemHdrType.
      MemberEndOffset += sizeof(object::BigArMemHdrType) +
                         alignTo(Data[I].Data.size(), 2) +
                         alignTo(Member.MemberName.size(), 2);
    }

    // AIX member table size.
    uint64_t MemberTableSize = 20 + // Number of members field
                               20 * MemberOffsets.size() +
                               MemberTableNameStrTblSize;

    SmallString<0> SymNamesBuf32;
    SmallString<0> SymNamesBuf64;
    raw_svector_ostream SymNames32(SymNamesBuf32);
    raw_svector_ostream SymNames64(SymNamesBuf64);

    if (ShouldWriteSymtab && NumSyms)
      // Generate the symbol names for the members.
      for (const auto &M : Data) {
        Expected<std::vector<unsigned>> SymbolsOrErr = getSymbols(
            M.SymFile.get(), 0,
            is64BitSymbolicFile(M.SymFile.get()) ? SymNames64 : SymNames32,
            nullptr);
        if (!SymbolsOrErr)
          return SymbolsOrErr.takeError();
      }

    uint64_t MemberTableEndOffset =
        LastMemberEndOffset +
        alignTo(sizeof(object::BigArMemHdrType) + MemberTableSize, 2);

    // In AIX OS, The 'GlobSymOffset' field in the fixed-length header contains
    // the offset to the 32-bit global symbol table, and the 'GlobSym64Offset'
    // contains the offset to the 64-bit global symbol table.
    uint64_t GlobalSymbolOffset =
        (ShouldWriteSymtab &&
         (WriteSymtab != SymtabWritingMode::BigArchive64) && NumSyms32 > 0)
            ? MemberTableEndOffset
            : 0;

    uint64_t GlobalSymbolOffset64 = 0;
    uint64_t NumSyms64 = NumSyms - NumSyms32;
    if (ShouldWriteSymtab && (WriteSymtab != SymtabWritingMode::BigArchive32) &&
        NumSyms64 > 0) {
      if (GlobalSymbolOffset == 0)
        GlobalSymbolOffset64 = MemberTableEndOffset;
      else
        // If there is a global symbol table for 32-bit members,
        // the 64-bit global symbol table is after the 32-bit one.
        GlobalSymbolOffset64 =
            GlobalSymbolOffset + sizeof(object::BigArMemHdrType) +
            (NumSyms32 + 1) * 8 + alignTo(SymNamesBuf32.size(), 2);
    }

    // Fixed Sized Header.
    printWithSpacePadding(Out, NewMembers.size() ? LastMemberEndOffset : 0,
                          20); // Offset to member table
    // If there are no file members in the archive, there will be no global
    // symbol table.
    printWithSpacePadding(Out, GlobalSymbolOffset, 20);
    printWithSpacePadding(Out, GlobalSymbolOffset64, 20);
    printWithSpacePadding(Out,
                          NewMembers.size()
                              ? sizeof(object::BigArchive::FixLenHdr) +
                                    Data[0].PreHeadPadSize
                              : 0,
                          20); // Offset to first archive member
    printWithSpacePadding(Out, NewMembers.size() ? LastMemberHeaderOffset : 0,
                          20); // Offset to last archive member
    printWithSpacePadding(
        Out, 0,
        20); // Offset to first member of free list - Not supported yet

    for (const MemberData &M : Data) {
      Out << std::string(M.PreHeadPadSize, '\0');
      Out << M.Header << M.Data;
      if (M.Data.size() % 2)
        Out << '\0';
    }

    if (NewMembers.size()) {
      // Member table.
      printBigArchiveMemberHeader(Out, "", sys::toTimePoint(0), 0, 0, 0,
                                  MemberTableSize, LastMemberHeaderOffset,
                                  GlobalSymbolOffset ? GlobalSymbolOffset
                                                     : GlobalSymbolOffset64);
      printWithSpacePadding(Out, MemberOffsets.size(), 20); // Number of members
      for (uint64_t MemberOffset : MemberOffsets)
        printWithSpacePadding(Out, MemberOffset,
                              20); // Offset to member file header.
      for (StringRef MemberName : MemberNames)
        Out << MemberName << '\0'; // Member file name, null byte padding.

      if (MemberTableNameStrTblSize % 2)
        Out << '\0'; // Name table must be tail padded to an even number of
                     // bytes.

      if (ShouldWriteSymtab) {
        // Write global symbol table for 32-bit file members.
        if (GlobalSymbolOffset) {
          writeSymbolTable(Out, Kind, Deterministic, Data, SymNamesBuf32,
                           *HeadersSize, NumSyms32, LastMemberEndOffset,
                           GlobalSymbolOffset64);
          // Add padding between the symbol tables, if needed.
          if (GlobalSymbolOffset64 && (SymNamesBuf32.size() % 2))
            Out << '\0';
        }

        // Write global symbol table for 64-bit file members.
        if (GlobalSymbolOffset64)
          writeSymbolTable(Out, Kind, Deterministic, Data, SymNamesBuf64,
                           *HeadersSize, NumSyms64,
                           GlobalSymbolOffset ? GlobalSymbolOffset
                                              : LastMemberEndOffset,
                           0, true);
      }
    }
  }
  Out.flush();
  return Error::success();
}

Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
                   SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
                   bool Deterministic, bool Thin,
                   std::unique_ptr<MemoryBuffer> OldArchiveBuf, bool IsEC) {
  Expected<sys::fs::TempFile> Temp =
      sys::fs::TempFile::create(ArcName + ".temp-archive-%%%%%%%.a");
  if (!Temp)
    return Temp.takeError();
  raw_fd_ostream Out(Temp->FD, false);

  if (Error E = writeArchiveToStream(Out, NewMembers, WriteSymtab, Kind,
                                     Deterministic, Thin, IsEC)) {
    if (Error DiscardError = Temp->discard())
      return joinErrors(std::move(E), std::move(DiscardError));
    return E;
  }

  // At this point, we no longer need whatever backing memory
  // was used to generate the NewMembers. On Windows, this buffer
  // could be a mapped view of the file we want to replace (if
  // we're updating an existing archive, say). In that case, the
  // rename would still succeed, but it would leave behind a
  // temporary file (actually the original file renamed) because
  // a file cannot be deleted while there's a handle open on it,
  // only renamed. So by freeing this buffer, this ensures that
  // the last open handle on the destination file, if any, is
  // closed before we attempt to rename.
  OldArchiveBuf.reset();

  return Temp->keep(ArcName);
}

Expected<std::unique_ptr<MemoryBuffer>>
writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers,
                     SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
                     bool Deterministic, bool Thin) {
  SmallVector<char, 0> ArchiveBufferVector;
  raw_svector_ostream ArchiveStream(ArchiveBufferVector);

  if (Error E = writeArchiveToStream(ArchiveStream, NewMembers, WriteSymtab,
                                     Kind, Deterministic, Thin, false))
    return std::move(E);

  return std::make_unique<SmallVectorMemoryBuffer>(
      std::move(ArchiveBufferVector), /*RequiresNullTerminator=*/false);
}

} // namespace llvm
