//===- 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 = false;
  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) {
    if (isa<object::MachOObjectFile>(**OptionalObject))
      return object::Archive::K_DARWIN;
    if (isa<object::XCOFFObjectFile>(**OptionalObject))
      return object::Archive::K_AIXBIG;
    if (isa<object::COFFObjectFile>(**OptionalObject) ||
        isa<object::COFFImportFile>(**OptionalObject))
      return object::Archive::K_COFF;
    return 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 object::Archive::getDefaultKindForTriple(TargetTriple);
    } else {
      // Squelch the error in case this was not a SymbolicFile.
      consumeError(ObjOrErr.takeError());
    }
  }

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

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,
                object::Archive::Kind Kind, function_ref<void(Error)> Warn) {
  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);
    // An error reading a bitcode file most likely indicates that the file
    // was created by a compiler from the future. Normally we don't try to
    // implement forwards compatibility for bitcode files, but when creating an
    // archive we can implement best-effort forwards compatibility by treating
    // the file as a blob and not creating symbol index entries for it. lld and
    // mold ignore the archive symbol index, so provided that you use one of
    // these linkers, LTO will work as long as lld or the gold plugin is newer
    // than the compiler. We only ignore errors if the archive format is one
    // that is supported by a linker that is known to ignore the index,
    // otherwise there's no chance of this working so we may as well error out.
    // We print a warning on read failure so that users of linkers that rely on
    // the symbol index can diagnose the issue.
    //
    // This is the same behavior as GNU ar when the linker plugin returns an
    // error when reading the input file. If the bitcode file is actually
    // malformed, it will be diagnosed at link time.
    if (!ObjOrErr) {
      switch (Kind) {
      case object::Archive::K_BSD:
      case object::Archive::K_GNU:
      case object::Archive::K_GNU64:
        Warn(ObjOrErr.takeError());
        return nullptr;
      case object::Archive::K_AIXBIG:
      case object::Archive::K_COFF:
      case object::Archive::K_DARWIN:
      case object::Archive::K_DARWIN64:
        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;
}

static bool isAnyArm64COFF(object::SymbolicFile &Obj) {
  if (Obj.isCOFF())
    return COFF::isAnyArm64(cast<COFFObjectFile>(&Obj)->getMachine());

  if (Obj.isCOFFImportFile())
    return COFF::isAnyArm64(cast<COFFImportFile>(&Obj)->getMachine());

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

  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->try_emplace(Name, Index).second)
        continue; // ignore duplicated symbol
      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,
                  std::optional<bool> IsEC, function_ref<void(Error)> Warn) {
  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;
  }

  std::vector<std::unique_ptr<SymbolicFile>> SymFiles;

  if (NeedSymbols != SymtabWritingMode::NoSymtab || isAIXBigArchive(Kind)) {
    for (const NewArchiveMember &M : NewMembers) {
      Expected<std::unique_ptr<SymbolicFile>> SymFileOrErr = getSymbolicFile(
          M.Buf->getMemBufferRef(), Context, Kind, [&](Error Err) {
            Warn(createFileError(M.MemberName, std::move(Err)));
          });
      if (!SymFileOrErr)
        return createFileError(M.MemberName, SymFileOrErr.takeError());
      SymFiles.push_back(std::move(*SymFileOrErr));
    }
  }

  if (SymMap) {
    if (IsEC) {
      SymMap->UseECMap = *IsEC;
    } else {
      // When IsEC is not specified by the caller, use it when we have both
      // any ARM64 object (ARM64 or ARM64EC) and any EC object (ARM64EC or
      // AMD64). This may be a single ARM64EC object, but may also be separate
      // ARM64 and AMD64 objects.
      bool HaveArm64 = false, HaveEC = false;
      for (std::unique_ptr<SymbolicFile> &SymFile : SymFiles) {
        if (!SymFile)
          continue;
        if (!HaveArm64)
          HaveArm64 = isAnyArm64COFF(*SymFile);
        if (!HaveEC)
          HaveEC = isECObject(*SymFile);
        if (HaveArm64 && HaveEC) {
          SymMap->UseECMap = true;
          break;
        }
      }
    }
  }

  // The big archive format needs to know the offset of the previous member
  // header.
  uint64_t PrevOffset = 0;
  uint64_t NextMemHeadPadSize = 0;

  for (uint32_t Index = 0; Index < NewMembers.size(); ++Index) {
    const NewArchiveMember *M = &NewMembers[Index];
    std::string Header;
    raw_string_ostream Out(Header);

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

    // 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);
    }

    std::unique_ptr<SymbolicFile> CurSymFile;
    if (!SymFiles.empty())
      CurSymFile = std::move(SymFiles[Index]);

    // 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 (Index + 1 != SymFiles.size()) {
        uint64_t OffsetToNextMemData =
            NextOffset + sizeof(object::BigArMemHdrType) +
            alignTo(NewMembers[Index + 1].MemberName.size(), 2);
        NextMemHeadPadSize =
            alignToPowerOf2(OffsetToNextMemData,
                            getMemberAlignment(SymFiles[Index + 1].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 + 1, 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(errnoAsErrorCode());

  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);
}

Error writeArchiveToStream(raw_ostream &Out,
                           ArrayRef<NewArchiveMember> NewMembers,
                           SymtabWritingMode WriteSymtab,
                           object::Archive::Kind Kind, bool Deterministic,
                           bool Thin, std::optional<bool> IsEC,
                           function_ref<void(Error)> Warn) {
  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;
  bool ShouldWriteSymtab = WriteSymtab != SymtabWritingMode::NoSymtab;

  // COFF symbol map uses 16-bit indexes, so we can't use it if there are too
  // many members. COFF format also requires symbol table presence, so use
  // GNU format when NoSymtab is requested.
  if (isCOFFArchive(Kind) && (NewMembers.size() > 0xfffe || !ShouldWriteSymtab))
    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;

  Expected<std::vector<MemberData>> DataOrErr = computeMemberData(
      StringTable, SymNames, Kind, Thin, Deterministic, WriteSymtab,
      isCOFFArchive(Kind) ? &SymMap : nullptr, Context, NewMembers, IsEC, Warn);
  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.

  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();
}

void warnToStderr(Error Err) {
  llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "warning: ");
}

Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
                   SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
                   bool Deterministic, bool Thin,
                   std::unique_ptr<MemoryBuffer> OldArchiveBuf,
                   std::optional<bool> IsEC, function_ref<void(Error)> Warn) {
  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, Warn)) {
    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,
                     function_ref<void(Error)> Warn) {
  SmallVector<char, 0> ArchiveBufferVector;
  raw_svector_ostream ArchiveStream(ArchiveBufferVector);

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

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

} // namespace llvm
