diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp
--- a/llvm/lib/Object/ArchiveWriter.cpp
+++ b/llvm/lib/Object/ArchiveWriter.cpp
@@ -310,6 +310,8 @@
   std::string Header;
   StringRef Data;
   StringRef Padding;
+  uint64_t PreHeadPadSize = 0;
+  std::unique_ptr<SymbolicFile> SymFile = nullptr;
 };
 } // namespace
 
@@ -421,21 +423,71 @@
   }
 }
 
-static Expected<bool> is64BitSymbolicFile(const StringRef &ObjStringRef) {
-  MemoryBufferRef ObjMbf(ObjStringRef, "");
-  // In the scenario when LLVMContext is populated SymbolicFile will contain a
-  // reference to it, thus SymbolicFile should be destroyed first.
-  LLVMContext Context;
-  Expected<std::unique_ptr<SymbolicFile>> ObjOrErr =
-      getSymbolFile(ObjMbf, Context);
-  if (!ObjOrErr)
-    return ObjOrErr.takeError();
+static bool is64BitSymbolicFile(const SymbolicFile *SymObj) {
+  return SymObj != nullptr ? SymObj->is64Bit() : false;
+}
 
-  // Treated non symbolic file types as false.
-  if (!*ObjOrErr)
-    return 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 loadable share object file,
+  // align at the minimum value.
+  if (AuxHeaderSize <
+      reinterpret_cast<const char *>(&AuxHeader->MaxAlignOfData) -
+          reinterpret_cast<const char *>(AuxHeader) + 2)
+    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 << (std::max(AuxHeader->MaxAlignOfText, AuxHeader->MaxAlignOfData) >
+                       Log2OfAIXPageSize
+                   ? Log2OfMaxAlign
+                   : Log2OfAlign);
+}
 
-  return (*ObjOrErr)->is64Bit();
+// 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(), 1);
 }
 
 static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind,
@@ -466,12 +518,8 @@
 
   for (const MemberData &M : Members) {
     if (isAIXBigArchive(Kind)) {
-      Expected<bool> Is64BitOrErr = is64BitSymbolicFile(M.Data);
-      // If there is an error, the error will be emit when 'computeMemberData'
-      // call 'getSymbol' function, we use consumeError here.
-      if (!Is64BitOrErr)
-        consumeError(Is64BitOrErr.takeError());
-      if (*Is64BitOrErr != Is64Bit) {
+      Pos += M.PreHeadPadSize;
+      if (is64BitSymbolicFile(M.SymFile.get()) != Is64Bit) {
         Pos += M.Header.size() + M.Data.size() + M.Padding.size();
         continue;
       }
@@ -494,32 +542,18 @@
     Out.write(uint8_t(0));
 }
 
-static Expected<std::vector<unsigned>>
-getSymbols(MemoryBufferRef Buf, raw_ostream &SymNames, bool &HasObject) {
-  // In the scenario when LLVMContext is populated SymbolicFile will contain a
-  // reference to it, thus SymbolicFile should be destroyed first.
-  LLVMContext Context;
-
+static Expected<std::vector<unsigned>> getSymbols(SymbolicFile *Obj,
+                                                  raw_ostream &SymNames) {
   std::vector<unsigned> Ret;
-  Expected<std::unique_ptr<SymbolicFile>> ObjOrErr =
-      getSymbolFile(Buf, Context);
-  if (!ObjOrErr)
-    return ObjOrErr.takeError();
-
-  // If the member is not a symbolic file, treated as no symbol.
-  if (!*ObjOrErr)
-    return Ret;
-
-  std::unique_ptr<object::SymbolicFile> Obj = std::move(*ObjOrErr);
-
-  HasObject = true;
-  for (const object::BasicSymbolRef &S : Obj->symbols()) {
-    if (!isArchiveSymbol(S))
-      continue;
-    Ret.push_back(SymNames.tell());
-    if (Error E = S.printName(SymNames))
-      return std::move(E);
-    SymNames << '\0';
+  if (Obj != nullptr) {
+    for (const object::BasicSymbolRef &S : Obj->symbols()) {
+      if (!isArchiveSymbol(S))
+        continue;
+      Ret.push_back(SymNames.tell());
+      if (Error E = S.printName(SymNames))
+        return std::move(E);
+      SymNames << '\0';
+    }
   }
   return Ret;
 }
@@ -527,10 +561,10 @@
 static Expected<std::vector<MemberData>>
 computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
                   object::Archive::Kind Kind, bool Thin, bool Deterministic,
-                  WriteSymTabType NeedSymbols,
+                  WriteSymTabType NeedSymbols, LLVMContext &Context,
                   ArrayRef<NewArchiveMember> NewMembers) {
   static char PaddingData[8] = {'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'};
-
+  static uint64_t MemHeadPadSize = 0;
   uint64_t Pos =
       isAIXBigArchive(Kind) ? sizeof(object::BigArchive::FixLenHdr) : 0;
 
@@ -595,11 +629,15 @@
   // The big archive format needs to know the offset of the previous member
   // header.
   unsigned PrevOffset = 0;
-  for (const NewArchiveMember &M : NewMembers) {
+  uint64_t NextMemHeadPadSize = 0;
+  std::unique_ptr<SymbolicFile> CurSymFile;
+  std::unique_ptr<SymbolicFile> NextSymFile;
+
+  for (auto M = NewMembers.begin(); M < NewMembers.end(); M++) {
     std::string Header;
     raw_string_ostream Out(Header);
 
-    MemoryBufferRef Buf = M.Buf->getMemBufferRef();
+    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
@@ -615,41 +653,90 @@
     sys::TimePoint<std::chrono::seconds> ModTime;
     if (UniqueTimestamps)
       // Increment timestamp for each file of a given name.
-      ModTime = sys::toTimePoint(FilenameCount[M.MemberName]++);
+      ModTime = sys::toTimePoint(FilenameCount[M->MemberName]++);
     else
-      ModTime = M.ModTime;
+      ModTime = M->ModTime;
 
     uint64_t Size = Buf.getBufferSize() + MemberPadding;
     if (Size > object::Archive::MaxMemberSize) {
       std::string StringMsg =
-          "File " + M.MemberName.str() + " exceeds size limit";
+          "File " + M->MemberName.str() + " exceeds size limit";
       return make_error<object::GenericBinaryError>(
           std::move(StringMsg), object::object_error::parse_failed);
     }
 
     if (isAIXBigArchive(Kind)) {
-      unsigned NextOffset = Pos + sizeof(object::BigArMemHdrType) +
-                            alignTo(M.MemberName.size(), 2) + alignTo(Size, 2);
-      printBigArchiveMemberHeader(Out, M.MemberName, ModTime, M.UID, M.GID,
-                                  M.Perms, Size, PrevOffset, NextOffset);
+      uint64_t OffsetToMemData = Pos + sizeof(object::BigArMemHdrType) +
+                                 alignTo(M->MemberName.size(), 2);
+
+      if (M == NewMembers.begin()) {
+        Expected<std::unique_ptr<SymbolicFile>> SymFileOrErr =
+            getSymbolFile(Buf, Context);
+        if (!SymFileOrErr)
+          return createFileError(M->MemberName, SymFileOrErr.takeError());
+        CurSymFile = std::move(*SymFileOrErr);
+
+        MemHeadPadSize = alignToPowerOf2(OffsetToMemData,
+                                         getMemberAlignment(CurSymFile.get())) -
+                         OffsetToMemData;
+      } else {
+        MemHeadPadSize = NextMemHeadPadSize;
+        CurSymFile = std::move(NextSymFile);
+      }
+      Pos += MemHeadPadSize;
+      uint64_t NextOffset = Pos + sizeof(object::BigArMemHdrType) +
+                            alignTo(M->MemberName.size(), 2) + alignTo(Size, 2);
+
+      // If there is next member file. we need to calculate the padding before
+      // the header if there is.
+      if ((M + 1) != NewMembers.end()) {
+        Expected<std::unique_ptr<SymbolicFile>> SymFileOrErr =
+            getSymbolFile((M + 1)->Buf->getMemBufferRef(), Context);
+        if (!SymFileOrErr)
+          return createFileError((M + 1)->MemberName, SymFileOrErr.takeError());
+
+        NextSymFile = std::move(*SymFileOrErr);
+        uint64_t OffsetToNextMemData = NextOffset +
+                                       sizeof(object::BigArMemHdrType) +
+                                       alignTo((M + 1)->MemberName.size(), 2);
+        NextMemHeadPadSize =
+            alignToPowerOf2(OffsetToNextMemData,
+                            getMemberAlignment(NextSymFile.get())) -
+            OffsetToNextMemData;
+        NextOffset += NextMemHeadPadSize;
+      }
+      printBigArchiveMemberHeader(Out, M->MemberName, ModTime, M->UID, M->GID,
+                                  M->Perms, Size, PrevOffset, NextOffset);
       PrevOffset = Pos;
     } else {
-      printMemberHeader(Out, Pos, StringTable, MemberNames, Kind, Thin, M,
+      printMemberHeader(Out, Pos, StringTable, MemberNames, Kind, Thin, *M,
                         ModTime, Size);
     }
     Out.flush();
 
     std::vector<unsigned> Symbols;
     if (NeedSymbols) {
+      if (!isAIXBigArchive(Kind)) {
+        Expected<std::unique_ptr<SymbolicFile>> SymFileOrErr =
+            getSymbolFile(Buf, Context);
+        if (!SymFileOrErr)
+          return createFileError(M->MemberName, SymFileOrErr.takeError());
+        CurSymFile = std::move(*SymFileOrErr);
+      }
+
       Expected<std::vector<unsigned>> SymbolsOrErr =
-          getSymbols(Buf, SymNames, HasObject);
+          getSymbols(CurSymFile.get(), SymNames);
       if (!SymbolsOrErr)
-        return createFileError(M.MemberName, SymbolsOrErr.takeError());
+        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});
+    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
@@ -714,9 +801,13 @@
   SmallString<0> StringTableBuf;
   raw_svector_ostream StringTable(StringTableBuf);
 
+  // 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, NewMembers);
+                        WriteSymtab, Context, NewMembers);
   if (Error E = DataOrErr.takeError())
     return E;
   std::vector<MemberData> &Data = *DataOrErr;
@@ -733,6 +824,7 @@
 
   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();
@@ -745,11 +837,7 @@
     // know the symbol number of 32-bit global symbol table and symbol number of
     // 64-bit global table.
     if (isAIXBigArchive(Kind) && WriteSymtab) {
-      Expected<bool> Is64BitOrErr = is64BitSymbolicFile(M.Data);
-      if (Error E = Is64BitOrErr.takeError())
-        return E;
-
-      if (!*Is64BitOrErr)
+      if (!is64BitSymbolicFile(M.SymFile.get()))
         NumSyms32 += M.Symbols.size();
     }
   }
@@ -814,13 +902,14 @@
     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);
+                         alignTo(Data[I].Data.size(), 2) +
+                         alignTo(Member.MemberName.size(), 2);
     }
 
     // AIX member table size.
@@ -828,22 +917,17 @@
                                20 * MemberOffsets.size() +
                                MemberTableNameStrTblSize;
 
-    SmallString<0> SymNamesBuf32;
+    SmallString<1> SymNamesBuf32;
     SmallString<0> SymNamesBuf64;
     raw_svector_ostream SymNames32(SymNamesBuf32);
     raw_svector_ostream SymNames64(SymNamesBuf64);
 
     if (WriteSymtab && NumSyms)
       // Generate the 32-bits object member symbol name string and 64-bits' one.
-      for (const NewArchiveMember &M : NewMembers) {
-        MemoryBufferRef Buf = M.Buf->getMemBufferRef();
-        Expected<bool> Is64BitOrErr = is64BitSymbolicFile(Buf.getBuffer());
-        if (!Is64BitOrErr)
-          consumeError(Is64BitOrErr.takeError());
-
-        bool HasObject;
-        Expected<std::vector<unsigned>> SymbolsOrErr =
-            getSymbols(Buf, *Is64BitOrErr ? SymNames64 : SymNames32, HasObject);
+      for (const auto &M : Data) {
+        Expected<std::vector<unsigned>> SymbolsOrErr = getSymbols(
+            M.SymFile.get(),
+            is64BitSymbolicFile(M.SymFile.get()) ? SymNames64 : SymNames32);
         if (!SymbolsOrErr)
           return SymbolsOrErr.takeError();
       }
@@ -883,9 +967,12 @@
     // symbol table.
     printWithSpacePadding(Out, NewMembers.size() ? GlobalSymbolOffset : 0, 20);
     printWithSpacePadding(Out, GlobalSymbolOffset64, 20);
-    printWithSpacePadding(
-        Out, NewMembers.size() ? sizeof(object::BigArchive::FixLenHdr) : 0,
-        20); // Offset to first archive member
+    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(
@@ -893,6 +980,8 @@
         20); // Offset to first member of free list - Not supported yet
 
     for (const MemberData &M : Data) {
+      for (uint64_t i = 0; i < M.PreHeadPadSize; i++)
+        Out << '\0';
       Out << M.Header << M.Data;
       if (M.Data.size() % 2)
         Out << '\0';
diff --git a/llvm/test/Object/archive-malformed-object.test b/llvm/test/Object/archive-malformed-object.test
--- a/llvm/test/Object/archive-malformed-object.test
+++ b/llvm/test/Object/archive-malformed-object.test
@@ -18,8 +18,8 @@
 
 # ERR2: error: bad.a: 'input.o': section header table goes past the end of the file: e_shoff = 0x9999
 
-## Don't emit an error if the symbol table is not required.
-# RUN: llvm-ar rcS good.a input.o input.bc
+## Don't emit an error if the symbol table is not required for gnu format.
+# RUN: llvm-ar --format=gnu rcS good.a input.o input.bc
 # RUN: llvm-ar t good.a | FileCheck %s --check-prefix=CONTENTS
 
 # CONTENTS:      input.o
diff --git a/llvm/test/tools/llvm-ar/big-archive-xcoff-auxi-head-align.test b/llvm/test/tools/llvm-ar/big-archive-xcoff-auxi-head-align.test
new file mode 100644
--- /dev/null
+++ b/llvm/test/tools/llvm-ar/big-archive-xcoff-auxi-head-align.test
@@ -0,0 +1,16 @@
+## Test the content of xcoff object file which has auxiliary header
+## is aligned in big archive basesd on the
+## MAX(maxinum aligment of .text, maxinum alignment of .data).
+
+# RUN: rm -rf %t && mkdir %t
+# RUN: cp %p/../llvm-readobj/XCOFF/Inputs/needed-libs*.o %t
+# RUN: cd %t
+# RUN: env OBJECT_MODE=32_64 llvm-ar -q t1.a needed-libs-64.o needed-libs-32.o
+# RUN: env OBJECT_MODE=32_64 llvm-ar -q t2.a needed-libs-32.o needed-libs-64.o
+# RUN: %python -c 'f=open("t1.a","rb");f.seek(384);print(f.read(2));f.close()' | FileCheck -check-prefix=MAGIC64 %s
+# RUN: %python -c 'f=open("t1.a","rb");f.seek(7296);print(f.read(2));f.close()' | FileCheck -check-prefix=MAGIC32 %s
+# RUN: %python -c 'f=open("t2.a","rb");f.seek(384);print(f.read(2));f.close()' | FileCheck -check-prefix=MAGIC32 %s
+# RUN: %python -c 'f=open("t2.a","rb");f.seek(6144);print(f.read(2));f.close()' | FileCheck -check-prefix=MAGIC64 %s
+
+# MAGIC64: b'\x01\xf7'
+# MAGIC32: b'\x01\xdf'