diff --git a/llvm/test/tools/llvm-ar/Inputs/xcoff.yaml b/llvm/test/tools/llvm-ar/Inputs/xcoff.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-ar/Inputs/xcoff.yaml @@ -0,0 +1,3 @@ +--- !XCOFF +FileHeader: + MagicNumber: 0x1DF diff --git a/llvm/test/tools/llvm-ar/default-xcoff.test b/llvm/test/tools/llvm-ar/default-xcoff.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-ar/default-xcoff.test @@ -0,0 +1,11 @@ +; REQUIRES: system-aix +;; Test llvm-ar do not big AIX archive write operation. + +; RUN: yaml2obj %S/Inputs/xcoff.yaml -o %t.obj +; RUN: rm -f %t.ar +; RUN: not --crash llvm-ar cr %t.ar %t.obj 2>&1 | FileCheck %s +; RUN: echo "test big archive" > %t.txt +; RUN: not --crash llvm-ar cr %t.ar %t.txt 2>&1 | FileCheck %s + +; CHECK: Unsupported big AIX write operation + diff --git a/llvm/tools/llvm-ar/llvm-ar.cpp b/llvm/tools/llvm-ar/llvm-ar.cpp --- a/llvm/tools/llvm-ar/llvm-ar.cpp +++ b/llvm/tools/llvm-ar/llvm-ar.cpp @@ -22,6 +22,7 @@ #include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Object/SymbolicFile.h" +#include "llvm/Object/XCOFFObjectFile.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ConvertUTF.h" @@ -881,9 +882,11 @@ } static object::Archive::Kind getDefaultForHost() { - return Triple(sys::getProcessTriple()).isOSDarwin() + Triple HostTriple(sys::getProcessTriple()); + return HostTriple.isOSDarwin() ? object::Archive::K_DARWIN - : object::Archive::K_GNU; + : (HostTriple.isOSAIX() ? object::Archive::K_AIXBIG + : object::Archive::K_GNU); } static object::Archive::Kind getKindFromMember(const NewArchiveMember &Member) { @@ -894,7 +897,9 @@ if (OptionalObject) return isa(**OptionalObject) ? object::Archive::K_DARWIN - : object::Archive::K_GNU; + : (isa(**OptionalObject) + ? object::Archive::K_AIXBIG + : object::Archive::K_GNU); // squelch the error in case we had a non-object file consumeError(OptionalObject.takeError()); @@ -939,6 +944,8 @@ else Kind = !NewMembers.empty() ? getKindFromMember(NewMembers.front()) : getDefaultForHost(); + if (Kind == object::Archive::K_AIXBIG) + llvm_unreachable("Unsupported big AIX write operation"); break; case GNU: Kind = object::Archive::K_GNU; @@ -1267,10 +1274,10 @@ arg = arg.drop_front(1); } } else { - if (ArchiveSpecified) fail("exactly one archive should be specified"); - ArchiveSpecified = true; - ArchiveName = arg.str(); + if (ArchiveSpecified) + ArchiveSpecified = true; + ArchiveName = arg.str(); } } if (!ArchiveSpecified) {