//===- 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/GOFFObjectFile.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;
    if (isa<object::GOFFObjectFile>(**OptionalObject))
      return object::Archive::K_ZOS;
    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 isZOSArchive(object::Archive::Kind Kind) {
  return Kind == object::Archive::K_ZOS;
}

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:
  case object::Archive::K_ZOS:
    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
printZOSMemberHeader(raw_ostream &Out, StringRef Name,
                     const sys::TimePoint<std::chrono::seconds> &ModTime,
                     unsigned UID, unsigned GID, unsigned Perms,
                     uint64_t Size) {
  std::string AHeader;
  raw_string_ostream AOut(AHeader);
  if (Name.size() <= 16) {
    printWithSpacePadding(AOut, Twine(Name), 16);
    printRestOfMemberHeader(AOut, ModTime, UID, GID, Perms, Size);
  } else {
    // z/OS ar stores the exact name length inline with no extra alignment
    // padding, unlike the BSD format which pads to an 8-byte boundary.
    printWithSpacePadding(AOut, Twine("#1/") + Twine(Name.size()), 16);
    printRestOfMemberHeader(AOut, ModTime, UID, GID, Perms, Name.size() + Size);
    AOut << Name;
  }
  SmallString<256> EHeader;
  if (std::error_code EC = ConverterEBCDIC::convertToEBCDIC(AHeader, EHeader))
    report_fatal_error(
        Twine("failed to convert z/OS member header to EBCDIC: ") +
        EC.message());
  Out << EHeader.str();
}

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:
  case object::Archive::K_ZOS:
    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, StringRef MemberName,
                  sys::TimePoint<std::chrono::seconds> ModTime, uint64_t Size) {
  if (isBSDLike(Kind))
    return printBSDMemberHeader(Out, Pos, MemberName, ModTime, M.UID, M.GID,
                                M.Perms, Size);
  if (isZOSArchive(Kind))
    return printZOSMemberHeader(Out, MemberName, ModTime, M.UID, M.GID, M.Perms,
                                Size);
  if (!useStringTable(Thin, MemberName))
    return printGNUSmallMemberHeader(Out, MemberName, ModTime, M.UID, M.GID,
                                     M.Perms, Size);
  Out << '/';
  uint64_t NamePos;
  if (Thin) {
    NamePos = StringTable.tell();
    StringTable << MemberName << "/\n";
  } else {
    auto Insertion = MemberNames.insert({MemberName, uint64_t(0)});
    if (Insertion.second) {
      Insertion.first->second = StringTable.tell();
      StringTable << 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;
  std::string HybridName = "";
  std::unique_ptr<MemoryBuffer> NativeBuf = 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";
  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
  // Each symbol table entry consists of a member offset.
  // For BSD, each entry also includes a string table offset.
  // For z/OS, each entry instead also includes a flag field.
  if (isBSDLike(Kind) || isZOSArchive(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 if (isZOSArchive(Kind)) {
    const char *Name = "__.SYMDEF";
    printZOSMemberHeader(Out, Name, now(Deterministic), 0, 0, 0, Size);
  } 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:
      case object::Archive::K_ZOS:
        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);

  // Padding size is not included in the Size field of the z/OS symbol table
  // header.
  int64_t HeaderSize = Size;
  if (isZOSArchive(Kind))
    HeaderSize -= Pad;

  writeSymbolTableHeader(Out, Kind, Deterministic, HeaderSize, 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
      // FIXME: Properly handle symbol attributes for z/OS archives.
      if (isZOSArchive(Kind))
        printNBits(Out, Kind, 0); // symbol flags
    }
    Pos += M.Header.size() + M.Data.size() + M.Padding.size();
  }

  if (isBSDLike(Kind))
    // byte count of the string table
    printNBits(Out, Kind, StringTable.size());
  if (isZOSArchive(Kind)) {
    SmallString<256> EStringTable;
    if (std::error_code EC =
            ConverterEBCDIC::convertToEBCDIC(StringTable, EStringTable))
      report_fatal_error(
          Twine("failed to convert z/OS symbol table to EBCDIC: ") +
          EC.message());
    Out << EStringTable.str();
  } else {
    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(std::move(*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(std::move(*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'};
  static char ZOSPaddingData[8] = {0x15, 0x15, 0x15, 0x15,
                                   0x15, 0x15, 0x15, 0x15}; // EBCDIC newlines.
  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;
  }

  uint32_t LastZosObjIndex =
      UINT_MAX; // Only set when writing symbol table in z/OS archive.

  for (const NewArchiveMember &M : NewMembers) {
    MemberData &D = Ret.emplace_back();
    D.Data = M.Buf->getBuffer();

    if (NeedSymbols != SymtabWritingMode::NoSymtab || isAIXBigArchive(Kind)) {
      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());
      D.SymFile = std::move(*SymFileOrErr);

      if (SymMap && D.SymFile.get()) {
        auto COFFObj = dyn_cast<COFFObjectFile>(D.SymFile.get());
        std::optional<MemoryBufferRef> HybridView;
        if (COFFObj && (HybridView = COFFObj->findHybridObjectSection())) {
          // Strip the hybrid section.
          D.NativeBuf = COFFObj->stripHybridSection();
          D.Data = D.NativeBuf->getBuffer();

          // Create a separate archive member for the hybrid ARM64X object.
          MemberData &ECData = Ret.emplace_back();
          ECData.Data = HybridView->getBuffer();

          SymFileOrErr =
              getSymbolicFile(*HybridView, Context, Kind, [&](Error Err) {
                Warn(createFileError(M.MemberName, std::move(Err)));
              });
          if (!SymFileOrErr)
            return createFileError(M.MemberName, SymFileOrErr.takeError());
          ECData.SymFile = std::move(*SymFileOrErr);

          // Use obj.arm64ec subdirectory for the hybrid object name.
          size_t Pos = M.MemberName.find_last_of("/\\");
          Pos = Pos == StringRef::npos ? 0 : Pos + 1;
          ECData.HybridName = (M.MemberName.substr(0, Pos) + "obj.arm64ec/" +
                               M.MemberName.substr(Pos))
                                  .str();
        }
      }

      if (isZOSArchive(Kind) && D.SymFile.get())
        LastZosObjIndex = Ret.size() - 1;
    }
  }

  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 (const MemberData &D : Ret) {
        if (!D.SymFile)
          continue;
        if (!HaveArm64)
          HaveArm64 = isAnyArm64COFF(*D.SymFile);
        if (!HaveEC)
          HaveEC = isECObject(*D.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, MemberIndex = 0; Index < Ret.size(); ++Index) {
    MemberData &D = Ret[Index];
    const NewArchiveMember *M = &NewMembers[MemberIndex];
    // Native COFF members (resulting from stripping a hybrid object section)
    // are followed by an extracted hybrid object member, using the same
    // NewArchiveMember.
    if (!D.NativeBuf.get())
      ++MemberIndex;
    raw_string_ostream Out(D.Header);

    uint64_t Size = D.Data.size();
    if (Thin)
      D.Data = "";

    // 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(D.Data.size(), Align(8)) : 0;

    StringRef MemberName = D.HybridName.size() ? D.HybridName : M->MemberName;

    // z/OS stores long member names inline using their exact byte length.
    // Include the inline name when computing alignment.
    uint64_t PaddingBase = D.Data.size() + MemberPadding;
    if (isZOSArchive(Kind) && MemberName.size() > 16)
      PaddingBase += MemberName.size();
    unsigned TailPadding = offsetToAlignment(PaddingBase, Align(2));
    D.Padding = StringRef(isZOSArchive(Kind) ? ZOSPaddingData : PaddingData,
                          MemberPadding + TailPadding);

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

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

    // 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(MemberName.size(), 2);

      if (Index == 0)
        NextMemHeadPadSize =
            alignToPowerOf2(OffsetToMemData,
                            getMemberAlignment(D.SymFile.get())) -
            OffsetToMemData;

      D.PreHeadPadSize = NextMemHeadPadSize;
      Pos += D.PreHeadPadSize;
      uint64_t NextOffset = Pos + sizeof(object::BigArMemHdrType) +
                            alignTo(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 != Ret.size()) {
        uint64_t OffsetToNextMemData =
            NextOffset + sizeof(object::BigArMemHdrType) +
            alignTo(NewMembers[MemberIndex].MemberName.size(), 2);
        NextMemHeadPadSize =
            alignToPowerOf2(OffsetToNextMemData,
                            getMemberAlignment(Ret[Index + 1].SymFile.get())) -
            OffsetToNextMemData;
        NextOffset += NextMemHeadPadSize;
      }
      printBigArchiveMemberHeader(Out, MemberName, ModTime, M->UID, M->GID,
                                  M->Perms, Size, PrevOffset, NextOffset);
      PrevOffset = Pos;
    } else {
      printMemberHeader(Out, Pos, StringTable, MemberNames, Kind, Thin, *M,
                        MemberName, ModTime, Size);
    }

    if (NeedSymbols != SymtabWritingMode::NoSymtab) {
      Expected<std::vector<unsigned>> SymbolsOrErr =
          getSymbols(D.SymFile.get(), Index + 1, SymNames, SymMap);
      if (!SymbolsOrErr)
        return createFileError(MemberName, SymbolsOrErr.takeError());
      D.Symbols = std::move(*SymbolsOrErr);
      if (D.SymFile)
        HasObject = true;
    }
    // On z/OS, when there are no symbols, add a dummy blank symbol
    // into the symbol table. This is done since the z/OS binder:
    //   - emits an error if there is no symbol table in the archive
    //   - emits an error if the symbol table has 0 symbols
    //   - should not find any references to a blank symbol
    if ((LastZosObjIndex == Index) && (SymNames.tell() == 0)) {
      D.Symbols.push_back(0);
      SymNames << ' ' << '\0';
    }

    Pos += D.Header.size() + D.Data.size() + D.Padding.size();
  }
  // 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) {
      switch (Kind) {
      case object::Archive::K_COFF:
        // COFF format has no 64-bit version, so we use GNU64 instead.
        if (!SymMap.Map.empty() && !SymMap.ECMap.empty())
          // Only the COFF format supports the ECSYMBOLS section, so don’t use
          // GNU64 when two symbol maps are required.
          return make_error<object::GenericBinaryError>(
              "Archive is too large: ARM64X does not support archives larger "
              "than 4GB");
        // Since this changes the headers, we need to recalculate everything.
        return writeArchiveToStream(Out, NewMembers, WriteSymtab,
                                    object::Archive::K_GNU64, Deterministic,
                                    Thin, IsEC, Warn);
      case object::Archive::K_DARWIN:
        Kind = object::Archive::K_DARWIN64;
        break;
      default:
        Kind = object::Archive::K_GNU64;
        break;
      }
      HeadersSize.reset();
    }
  }

  if (Thin)
    Out << "!<thin>\n";
  else if (isAIXBigArchive(Kind))
    Out << "<bigaf>\n";
  else if (isZOSArchive(Kind))
    Out << ZOSArchiveMagic;
  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
