[clang] f740bcb - [AIX] supporting -X options for llvm-ranlib in AIX OS
via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 22 06:42:00 PDT 2023
Author: zhijian
Date: 2023-08-22T09:41:33-04:00
New Revision: f740bcb3707a17ed4ccd52157089011a586cc2a6
URL: https://github.com/llvm/llvm-project/commit/f740bcb3707a17ed4ccd52157089011a586cc2a6
DIFF: https://github.com/llvm/llvm-project/commit/f740bcb3707a17ed4ccd52157089011a586cc2a6.diff
LOG: [AIX] supporting -X options for llvm-ranlib in AIX OS
Summary:
llvm-ar is symlinked as llvm-ranlib and will act as ranlib when invoked in that mode. llvm-ar since [[ https://github.ibm.com/compiler/llvm-project/commit/4f2cfbe5314b064625b2c87bde6ce5c8d04004c5 | compiler/llvm-project at 4f2cfbe ]] supports the -X options, but doesn't seem to accept them when running as llvm-ranlib.
In AIX OS , according to https://www.ibm.com/docs/en/aix/7.2?topic=r-ranlib-command
-X mode Specifies the type of object file ranlib should examine. The mode must be one of the following:
32
Processes only 32-bit object files
64
Processes only 64-bit object files
32_64, any
Processes both 32-bit and 64-bit object files
The default is to process 32-bit object files (ignore 64-bit objects). The mode can also be set with the OBJECT_MODE environment variable. For example, OBJECT_MODE=64 causes ranlib to process any 64-bit objects and ignore 32-bit objects. The -X flag overrides the OBJECT_MODE variable.
Reviewers: James Henderson, MaskRay, Stephen Peckham
Differential Revision: https://reviews.llvm.org/D142660
Added:
llvm/test/tools/llvm-ranlib/AIX-X-option-non-AIX.test
llvm/test/tools/llvm-ranlib/aix-X-option.test
Modified:
clang/lib/Driver/OffloadBundler.cpp
clang/test/lit.cfg.py
clang/tools/clang-offload-packager/ClangOffloadPackager.cpp
llvm/include/llvm/Object/Archive.h
llvm/include/llvm/Object/ArchiveWriter.h
llvm/lib/ObjCopy/Archive.cpp
llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
llvm/lib/Object/Archive.cpp
llvm/lib/Object/ArchiveWriter.cpp
llvm/lib/Object/COFFImportFile.cpp
llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
llvm/tools/llvm-ar/llvm-ar.cpp
llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
Removed:
################################################################################
diff --git a/clang/lib/Driver/OffloadBundler.cpp b/clang/lib/Driver/OffloadBundler.cpp
index 0ddfb07fdad5ba..d11c41605bf39e 100644
--- a/clang/lib/Driver/OffloadBundler.cpp
+++ b/clang/lib/Driver/OffloadBundler.cpp
@@ -1265,8 +1265,9 @@ Error OffloadBundler::UnbundleArchive() {
OutputArchivesMap.find(Target);
if (CurArchiveMembers != OutputArchivesMap.end()) {
if (Error WriteErr = writeArchive(FileName, CurArchiveMembers->getValue(),
- true, getDefaultArchiveKindForHost(),
- true, false, nullptr))
+ SymtabWritingMode::NormalSymtab,
+ getDefaultArchiveKindForHost(), true,
+ false, nullptr))
return WriteErr;
} else if (!BundlerConfig.AllowMissingBundles) {
std::string ErrMsg =
@@ -1280,9 +1281,9 @@ Error OffloadBundler::UnbundleArchive() {
// the missing input file.
std::vector<llvm::NewArchiveMember> EmptyArchive;
EmptyArchive.clear();
- if (Error WriteErr = writeArchive(FileName, EmptyArchive, true,
- getDefaultArchiveKindForHost(), true,
- false, nullptr))
+ if (Error WriteErr = writeArchive(
+ FileName, EmptyArchive, SymtabWritingMode::NormalSymtab,
+ getDefaultArchiveKindForHost(), true, false, nullptr))
return WriteErr;
}
}
diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py
index 68e038475a5c75..815ea219aaa81e 100644
--- a/clang/test/lit.cfg.py
+++ b/clang/test/lit.cfg.py
@@ -380,16 +380,15 @@ def exclude_unsupported_files_for_aix(dirname):
elif platform.system() == "AIX":
config.environment["AIXTHREAD_STK"] = "4194304"
-# The llvm-nm tool supports an environment variable "OBJECT_MODE" on AIX OS, which
+# Some tools support an environment variable "OBJECT_MODE" on AIX OS, which
# controls the kind of objects they will support. If there is no "OBJECT_MODE"
# environment variable specified, the default behaviour is to support 32-bit
# objects only. In order to not affect most test cases, which expect to support
# 32-bit and 64-bit objects by default, set the environment variable
-# "OBJECT_MODE" to 'any' for llvm-nm on AIX OS.
+# "OBJECT_MODE" to "any" by default on AIX OS.
if "system-aix" in config.available_features:
- config.substitutions.append(("llvm-nm", "env OBJECT_MODE=any llvm-nm"))
- config.substitutions.append(("llvm-ar", "env OBJECT_MODE=any llvm-ar"))
+ config.environment["OBJECT_MODE"] = "any"
# It is not realistically possible to account for all options that could
# possibly be present in system and user configuration files, so disable
diff --git a/clang/tools/clang-offload-packager/ClangOffloadPackager.cpp b/clang/tools/clang-offload-packager/ClangOffloadPackager.cpp
index f028ea9a20a58f..7100727015e7b7 100644
--- a/clang/tools/clang-offload-packager/ClangOffloadPackager.cpp
+++ b/clang/tools/clang-offload-packager/ClangOffloadPackager.cpp
@@ -192,9 +192,9 @@ static Error unbundleImages() {
Binary->getImage(),
Binary->getMemoryBufferRef().getBufferIdentifier()));
- if (Error E = writeArchive(Args["file"], Members, true,
- Archive::getDefaultKindForHost(), true, false,
- nullptr))
+ if (Error E = writeArchive(
+ Args["file"], Members, SymtabWritingMode::NormalSymtab,
+ Archive::getDefaultKindForHost(), true, false, nullptr))
return E;
} else if (Args.count("file")) {
if (Extracted.size() > 1)
diff --git a/llvm/include/llvm/Object/Archive.h b/llvm/include/llvm/Object/Archive.h
index 27f504779c4f52..3dd99a46507a24 100644
--- a/llvm/include/llvm/Object/Archive.h
+++ b/llvm/include/llvm/Object/Archive.h
@@ -411,12 +411,17 @@ class BigArchive : public Archive {
uint64_t FirstChildOffset = 0;
uint64_t LastChildOffset = 0;
std::string MergedGlobalSymtabBuf;
+ bool Has32BitGlobalSymtab = false;
+ bool Has64BitGlobalSymtab = false;
public:
BigArchive(MemoryBufferRef Source, Error &Err);
uint64_t getFirstChildOffset() const override { return FirstChildOffset; }
uint64_t getLastChildOffset() const { return LastChildOffset; }
bool isEmpty() const override { return getFirstChildOffset() == 0; }
+
+ bool has32BitGlobalSymtab() { return Has32BitGlobalSymtab; }
+ bool has64BitGlobalSymtab() { return Has64BitGlobalSymtab; }
};
} // end namespace object
diff --git a/llvm/include/llvm/Object/ArchiveWriter.h b/llvm/include/llvm/Object/ArchiveWriter.h
index c89246f1d5694e..7f915929cd7219 100644
--- a/llvm/include/llvm/Object/ArchiveWriter.h
+++ b/llvm/include/llvm/Object/ArchiveWriter.h
@@ -40,8 +40,16 @@ struct NewArchiveMember {
Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To);
+enum class SymtabWritingMode {
+ NoSymtab, // Do not write symbol table.
+ NormalSymtab, // Write symbol table. For the Big Archive format, write both
+ // 32-bit and 64-bit symbol tables.
+ BigArchive32, // Only write the 32-bit symbol table.
+ BigArchive64 // Only write the 64-bit symbol table.
+};
+
Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
- bool WriteSymtab, object::Archive::Kind Kind,
+ SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
bool Deterministic, bool Thin,
std::unique_ptr<MemoryBuffer> OldArchiveBuf = nullptr,
bool IsEC = false);
@@ -49,8 +57,9 @@ Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
// writeArchiveToBuffer is similar to writeArchive but returns the Archive in a
// buffer instead of writing it out to a file.
Expected<std::unique_ptr<MemoryBuffer>>
-writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers, bool WriteSymtab,
- object::Archive::Kind Kind, bool Deterministic, bool Thin);
+writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers,
+ SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
+ bool Deterministic, bool Thin);
}
#endif
diff --git a/llvm/lib/ObjCopy/Archive.cpp b/llvm/lib/ObjCopy/Archive.cpp
index 742ca0b890cf26..b6da4dc1e239c8 100644
--- a/llvm/lib/ObjCopy/Archive.cpp
+++ b/llvm/lib/ObjCopy/Archive.cpp
@@ -60,8 +60,9 @@ createNewArchiveMembers(const MultiFormatConfig &Config, const Archive &Ar) {
// For thin archives it writes the archive file itself as well as its members.
static Error deepWriteArchive(StringRef ArcName,
ArrayRef<NewArchiveMember> NewMembers,
- bool WriteSymtab, object::Archive::Kind Kind,
- bool Deterministic, bool Thin) {
+ SymtabWritingMode WriteSymtab,
+ object::Archive::Kind Kind, bool Deterministic,
+ bool Thin) {
if (Kind == object::Archive::K_BSD && !NewMembers.empty() &&
NewMembers.front().detectKindFromObject() == object::Archive::K_DARWIN)
Kind = object::Archive::K_DARWIN;
@@ -102,8 +103,10 @@ Error executeObjcopyOnArchive(const MultiFormatConfig &Config,
return NewArchiveMembersOrErr.takeError();
const CommonConfig &CommonConfig = Config.getCommonConfig();
return deepWriteArchive(CommonConfig.OutputFilename, *NewArchiveMembersOrErr,
- Ar.hasSymbolTable(), Ar.kind(),
- CommonConfig.DeterministicArchives, Ar.isThin());
+ Ar.hasSymbolTable() ? SymtabWritingMode::NormalSymtab
+ : SymtabWritingMode::NoSymtab,
+ Ar.kind(), CommonConfig.DeterministicArchives,
+ Ar.isThin());
}
} // end namespace objcopy
diff --git a/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp b/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
index e26b363df21cc9..9d55c3d8a1a486 100644
--- a/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
@@ -490,10 +490,12 @@ Error objcopy::macho::executeObjcopyOnMachOUniversalBinary(
if (Kind == object::Archive::K_BSD)
Kind = object::Archive::K_DARWIN;
Expected<std::unique_ptr<MemoryBuffer>> OutputBufferOrErr =
- writeArchiveToBuffer(*NewArchiveMembersOrErr,
- (*ArOrErr)->hasSymbolTable(), Kind,
- Config.getCommonConfig().DeterministicArchives,
- (*ArOrErr)->isThin());
+ writeArchiveToBuffer(
+ *NewArchiveMembersOrErr,
+ (*ArOrErr)->hasSymbolTable() ? SymtabWritingMode::NormalSymtab
+ : SymtabWritingMode::NoSymtab,
+ Kind, Config.getCommonConfig().DeterministicArchives,
+ (*ArOrErr)->isThin());
if (!OutputBufferOrErr)
return OutputBufferOrErr.takeError();
Expected<std::unique_ptr<Binary>> BinaryOrErr =
diff --git a/llvm/lib/Object/Archive.cpp b/llvm/lib/Object/Archive.cpp
index 9920145a2f3c19..bf9a1ce1de88bb 100644
--- a/llvm/lib/Object/Archive.cpp
+++ b/llvm/lib/Object/Archive.cpp
@@ -1392,6 +1392,8 @@ BigArchive::BigArchive(MemoryBufferRef Source, Error &Err)
GlobSymtab32Loc, GlobSymtab32Size, "32-bit");
if (Err)
return;
+
+ Has32BitGlobalSymtab = true;
}
if (GlobSymtab64Offset) {
@@ -1400,6 +1402,8 @@ BigArchive::BigArchive(MemoryBufferRef Source, Error &Err)
GlobSymtab64Loc, GlobSymtab64Size, "64-bit");
if (Err)
return;
+
+ Has64BitGlobalSymtab = true;
}
SmallVector<GlobalSymtabInfo> SymtabInfos;
diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp
index d79a5c6bef302e..abd25c4a846094 100644
--- a/llvm/lib/Object/ArchiveWriter.cpp
+++ b/llvm/lib/Object/ArchiveWriter.cpp
@@ -680,7 +680,7 @@ getSymbols(MemoryBufferRef Buf, uint16_t Index, raw_ostream &SymNames,
static Expected<std::vector<MemberData>>
computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
object::Archive::Kind Kind, bool Thin, bool Deterministic,
- bool NeedSymbols, SymMap *SymMap,
+ SymtabWritingMode NeedSymbols, SymMap *SymMap,
ArrayRef<NewArchiveMember> NewMembers) {
static char PaddingData[8] = {'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'};
@@ -796,7 +796,7 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
Out.flush();
std::vector<unsigned> Symbols;
- if (NeedSymbols) {
+ if (NeedSymbols != SymtabWritingMode::NoSymtab) {
Expected<std::vector<unsigned>> SymbolsOrErr =
getSymbols(Buf, Index, SymNames, SymMap, HasObject);
if (!SymbolsOrErr)
@@ -860,7 +860,8 @@ Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To) {
static Error writeArchiveToStream(raw_ostream &Out,
ArrayRef<NewArchiveMember> NewMembers,
- bool WriteSymtab, object::Archive::Kind Kind,
+ SymtabWritingMode WriteSymtab,
+ object::Archive::Kind Kind,
bool Deterministic, bool Thin, bool IsEC) {
assert((!Thin || !isBSDLike(Kind)) && "Only the gnu format has a thin mode");
@@ -897,6 +898,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
uint64_t LastMemberHeaderOffset = 0;
uint64_t NumSyms = 0;
uint64_t NumSyms32 = 0; // Store symbol number of 32-bit member files.
+ bool ShouldWriteSymtab = WriteSymtab != SymtabWritingMode::NoSymtab;
for (const auto &M : Data) {
// Record the start of the member's offset
@@ -910,7 +912,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
// 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) && WriteSymtab) {
+ if (isAIXBigArchive(Kind) && ShouldWriteSymtab) {
Expected<bool> Is64BitOrErr = is64BitSymbolicFile(M.Data);
if (Error E = Is64BitOrErr.takeError())
return E;
@@ -924,7 +926,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
// 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 (WriteSymtab && !is64BitKind(Kind)) {
+ 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(),
@@ -962,7 +964,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
Out << "!<arch>\n";
if (!isAIXBigArchive(Kind)) {
- if (WriteSymtab) {
+ if (ShouldWriteSymtab) {
if (!HeadersSize)
HeadersSize = computeHeadersSize(
Kind, Data.size(), StringTableSize, NumSyms, SymNamesBuf.size(),
@@ -978,7 +980,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
Out << StringTableMember.Header << StringTableMember.Data
<< StringTableMember.Padding;
- if (WriteSymtab && SymMap.ECMap.size())
+ if (ShouldWriteSymtab && SymMap.ECMap.size())
writeECSymbols(Out, Kind, Deterministic, Data, SymMap);
for (const MemberData &M : Data)
@@ -1017,7 +1019,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
raw_svector_ostream SymNames32(SymNamesBuf32);
raw_svector_ostream SymNames64(SymNamesBuf64);
- if (WriteSymtab && NumSyms)
+ if (ShouldWriteSymtab && NumSyms)
// Generate the symbol names for the members.
for (const NewArchiveMember &M : NewMembers) {
MemoryBufferRef Buf = M.Buf->getMemBufferRef();
@@ -1041,11 +1043,15 @@ static Error writeArchiveToStream(raw_ostream &Out,
// 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 =
- (WriteSymtab && NumSyms32 > 0) ? MemberTableEndOffset : 0;
+ (ShouldWriteSymtab &&
+ (WriteSymtab != SymtabWritingMode::BigArchive64) && NumSyms32 > 0)
+ ? MemberTableEndOffset
+ : 0;
uint64_t GlobalSymbolOffset64 = 0;
uint64_t NumSyms64 = NumSyms - NumSyms32;
- if (WriteSymtab && NumSyms64 > 0) {
+ if (ShouldWriteSymtab && (WriteSymtab != SymtabWritingMode::BigArchive32) &&
+ NumSyms64 > 0) {
if (GlobalSymbolOffset == 0)
GlobalSymbolOffset64 = MemberTableEndOffset;
else
@@ -1095,7 +1101,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
Out << '\0'; // Name table must be tail padded to an even number of
// bytes.
- if (WriteSymtab) {
+ if (ShouldWriteSymtab) {
// Write global symbol table for 32-bit file members.
if (GlobalSymbolOffset) {
writeSymbolTable(Out, Kind, Deterministic, Data, SymNamesBuf32,
@@ -1121,7 +1127,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
}
Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
- bool WriteSymtab, object::Archive::Kind Kind,
+ SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
bool Deterministic, bool Thin,
std::unique_ptr<MemoryBuffer> OldArchiveBuf, bool IsEC) {
Expected<sys::fs::TempFile> Temp =
@@ -1153,9 +1159,9 @@ Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
}
Expected<std::unique_ptr<MemoryBuffer>>
-writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers, bool WriteSymtab,
- object::Archive::Kind Kind, bool Deterministic,
- bool Thin) {
+writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers,
+ SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
+ bool Deterministic, bool Thin) {
SmallVector<char, 0> ArchiveBufferVector;
raw_svector_ostream ArchiveStream(ArchiveBufferVector);
diff --git a/llvm/lib/Object/COFFImportFile.cpp b/llvm/lib/Object/COFFImportFile.cpp
index f20fa9ff6f3230..5e3508ba34aec5 100644
--- a/llvm/lib/Object/COFFImportFile.cpp
+++ b/llvm/lib/Object/COFFImportFile.cpp
@@ -610,7 +610,7 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,
OF.createShortImport(*Name, E.Ordinal, ImportType, NameType));
}
- return writeArchive(Path, Members, /*WriteSymtab*/ true,
+ return writeArchive(Path, Members, SymtabWritingMode::NormalSymtab,
MinGW ? object::Archive::K_GNU : object::Archive::K_COFF,
/*Deterministic*/ true, /*Thin*/ false);
}
diff --git a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
index 158bbbdfc9b897..1c140edb07ac73 100644
--- a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
+++ b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
@@ -482,12 +482,10 @@ int llvm::libDriverMain(ArrayRef<const char *> ArgsArr) {
std::reverse(Members.begin(), Members.end());
bool Thin = Args.hasArg(OPT_llvmlibthin);
- if (Error E =
- writeArchive(OutputPath, Members,
- /*WriteSymtab=*/true,
- Thin ? object::Archive::K_GNU : object::Archive::K_COFF,
- /*Deterministic*/ true, Thin, nullptr,
- COFF::isArm64EC(LibMachine))) {
+ if (Error E = writeArchive(
+ OutputPath, Members, SymtabWritingMode::NormalSymtab,
+ Thin ? object::Archive::K_GNU : object::Archive::K_COFF,
+ /*Deterministic=*/true, Thin, nullptr, COFF::isArm64EC(LibMachine))) {
handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
llvm::errs() << OutputPath << ": " << EI.message() << "\n";
});
diff --git a/llvm/test/tools/llvm-ranlib/AIX-X-option-non-AIX.test b/llvm/test/tools/llvm-ranlib/AIX-X-option-non-AIX.test
new file mode 100644
index 00000000000000..537fe09219ec1f
--- /dev/null
+++ b/llvm/test/tools/llvm-ranlib/AIX-X-option-non-AIX.test
@@ -0,0 +1,6 @@
+# UNSUPPORTED: system-aix
+## Test the -X option is not supported on non-AIX os.
+
+# RUN: not llvm-ranlib -X32 2>&1 | FileCheck --implicit-check-not="error:" --check-prefix=INVALID-X-OPTION %s
+
+# INVALID-X-OPTION: error: -X32 option not supported on non AIX OS
diff --git a/llvm/test/tools/llvm-ranlib/aix-X-option.test b/llvm/test/tools/llvm-ranlib/aix-X-option.test
new file mode 100644
index 00000000000000..60b849d3bd4941
--- /dev/null
+++ b/llvm/test/tools/llvm-ranlib/aix-X-option.test
@@ -0,0 +1,130 @@
+# REQUIRES: system-aix
+## Test the -X option.
+## The option specifies the type of object file on which llvm-ranlib will operate.
+
+# RUN: rm -rf %t && mkdir %t && cd %t
+# RUN: yaml2obj --docnum=1 -DFLAG=0x1DF %s -o t32_1.o
+# RUN: yaml2obj --docnum=1 -DFLAG=0x1F7 %s -o t64_1.o
+# RUN: yaml2obj --docnum=2 -DFLAG=0x1DF %s -o t32_2.o
+# RUN: yaml2obj --docnum=2 -DFLAG=0x1F7 %s -o t64_2.o
+
+# RUN: llvm-ar qS t_all.a t32_1.o t64_1.o t32_2.o t64_2.o
+# RUN: cp t_all.a t_X32.a
+# RUN: cp t_all.a t_X64.a
+# RUN: cp t_all.a t_X32_64.a
+
+## Test the OBJECT_MODE environment variable when adding symbol table.
+# RUN: unset OBJECT_MODE
+# RUN: llvm-ranlib t_X32.a
+# RUN: llvm-nm --print-armap t_X32.a 2>&1 | FileCheck --check-prefixes=GLOB32 --implicit-check-not="in t64" %s
+# RUN: cp t_all.a t_X32.a
+# RUN: env OBJECT_MODE=32 llvm-ranlib t_X32.a
+# RUN: llvm-nm --print-armap t_X32.a 2>&1 | FileCheck --check-prefixes=GLOB32 --implicit-check-not="in t64" %s
+
+# RUN: env OBJECT_MODE=64 llvm-ranlib t_X64.a
+# RUN: llvm-nm --print-armap t_X64.a 2>&1 | FileCheck --check-prefixes=GLOB64 --implicit-check-not="in t32" %s
+
+# RUN: env OBJECT_MODE=32_64 llvm-ranlib t_X32_64.a
+# RUN: llvm-nm --print-armap t_X32_64.a 2>&1 | FileCheck --check-prefixes=GLOB32,GLOB64 %s
+# RUN: cp t_all.a t_X32_64.a
+# RUN: env OBJECT_MODE=any llvm-ranlib t_X32_64.a
+# RUN: llvm-nm --print-armap t_X32_64.a 2>&1 | FileCheck --check-prefixes=GLOB32,GLOB64 %s
+
+# RUN: cp t_all.a t_X32.a
+# RUN: cp t_all.a t_X64.a
+# RUN: cp t_all.a t_X32_64.a
+
+## Test the -X option when adding symbol table.
+# RUN: llvm-ranlib -X32 t_X32.a
+# RUN: llvm-nm --print-armap t_X32.a 2>&1 | FileCheck --check-prefixes=GLOB32 --implicit-check-not="in t64" %s
+# RUN: llvm-ranlib -X64 t_X32.a
+# RUN: llvm-nm --print-armap t_X32.a 2>&1 | FileCheck --check-prefixes=GLOB32,GLOB64 %s
+
+# RUN: llvm-ranlib -X64 t_X64.a
+# RUN: llvm-nm --print-armap t_X64.a 2>&1 | FileCheck --check-prefixes=GLOB64 --implicit-check-not="in t32" %s
+# RUN: llvm-ranlib -X32 t_X64.a
+# RUN: llvm-nm --print-armap t_X32.a 2>&1 | FileCheck --check-prefixes=GLOB32,GLOB64 %s
+
+# RUN: llvm-ranlib -X32_64 t_X32_64.a
+# RUN: llvm-nm --print-armap t_X32_64.a 2>&1 | FileCheck --check-prefixes=GLOB32,GLOB64 %s
+# RUN: cp t_all.a t_X32_64.a
+# RUN: llvm-ranlib -Xany t_X32_64.a
+# RUN: llvm-nm --print-armap t_X32_64.a 2>&1 | FileCheck --check-prefixes=GLOB32,GLOB64 %s
+
+# RUN: cp t_all.a t_X32.a
+# RUN: cp t_all.a t_X64.a
+
+## Test that the -X option will override the "OBJECT_MODE" environment variable.
+# RUN: env OBJECT_MODE=32_64 llvm-ranlib -X32 t_X32.a
+# RUN: llvm-nm --print-armap t_X32.a 2>&1 | FileCheck --check-prefixes=GLOB32 --implicit-check-not="in t64" %s
+
+# RUN: env OBJECT_MODE=32 llvm-ranlib -X64 t_X64.a
+# RUN: llvm-nm --print-armap t_X64.a 2>&1 | FileCheck --check-prefixes=GLOB64 --implicit-check-not="in t32" %s
+
+# GLOB32: sym1_0x1DF in t32_1.o
+# GLOB32-NEXT: sym2_0x1DF in t32_1.o
+# GLOB32-NEXT: sym3_0x1DF in t32_2.o
+# GLOB32-NEXT: sym4_0x1DF in t32_2.o
+
+# GLOB64: sym1_0x1F7 in t64_1.o
+# GLOB64-NEXT: sym2_0x1F7 in t64_1.o
+# GLOB64-NEXT: sym3_0x1F7 in t64_2.o
+# GLOB64-NEXT: sym4_0x1F7 in t64_2.o
+
+## Test invalid -X option and OBJECT_MODE enviornment var.
+# RUN: not env OBJECT_MODE= llvm-ranlib t_X32.a 2>&1 | FileCheck --implicit-check-not="error:" --check-prefixes=INVALID-OBJECT-MODE %s
+# RUN: not env OBJECT_MODE="" llvm-ranlib t_X32.a 2>&1 | FileCheck --implicit-check-not="error:" --check-prefixes=INVALID-OBJECT-MODE %s
+# RUN: not env OBJECT_MODE=31 llvm-ranlib t_X64.a 2>&1 | FileCheck --implicit-check-not="error:" --check-prefixes=INVALID-OBJECT-MODE %s
+# RUN: not llvm-ranlib -X t_X64.a 2>&1 | FileCheck --implicit-check-not="error:" --check-prefixes=INVALID-X-OPTION %s
+# RUN: not llvm-ranlib -X31 t_X64.a 2>&1 | FileCheck --implicit-check-not="error:" --check-prefixes=INVALID-X-OPTION %s
+
+# INVALID-OBJECT-MODE: error: the OBJECT_MODE environment variable has an invalid value. OBJECT_MODE must be 32, 64, 32_64, or any
+# INVALID-X-OPTION: error: the specified object mode is not valid. Specify -X32, -X64, -X32_64, or -Xany
+
+--- !XCOFF
+FileHeader:
+ MagicNumber: [[FLAG]]
+Sections:
+ - Name: .data
+ Flags: [ STYP_DATA ]
+Symbols:
+ - Name: sym1_[[FLAG]]
+ Section: .data
+ Type: 0x4000
+ StorageClass: C_EXT
+ AuxEntries:
+ - Type: AUX_CSECT
+ SymbolAlignmentAndType: 0x09
+ StorageMappingClass: XMC_RW
+ - Name: sym2_[[FLAG]]
+ Section: .data
+ Type: 0x4000
+ StorageClass: C_EXT
+ AuxEntries:
+ - Type: AUX_CSECT
+ SymbolAlignmentAndType: 0x09
+ StorageMappingClass: XMC_RW
+
+--- !XCOFF
+FileHeader:
+ MagicNumber: [[FLAG]]
+Sections:
+ - Name: .text
+ Flags: [ STYP_DATA ]
+Symbols:
+ - Name: sym3_[[FLAG]]
+ Section: .text
+ Type: 0x4000
+ StorageClass: C_EXT
+ AuxEntries:
+ - Type: AUX_CSECT
+ SymbolAlignmentAndType: 0x09
+ StorageMappingClass: XMC_PR
+ - Name: sym4_[[FLAG]]
+ Section: .text
+ Type: 0x4000
+ StorageClass: C_EXT
+ AuxEntries:
+ - Type: AUX_CSECT
+ SymbolAlignmentAndType: 0x09
+ StorageMappingClass: XMC_PR
diff --git a/llvm/tools/llvm-ar/llvm-ar.cpp b/llvm/tools/llvm-ar/llvm-ar.cpp
index d21650d146a9e6..9889ad9de627d5 100644
--- a/llvm/tools/llvm-ar/llvm-ar.cpp
+++ b/llvm/tools/llvm-ar/llvm-ar.cpp
@@ -69,7 +69,9 @@ static void printRanLibHelp(StringRef ToolName) {
<< " -v --version - Display the version of this program\n"
<< " -D - Use zero for timestamps and uids/gids "
"(default)\n"
- << " -U - Use actual timestamps and uids/gids\n";
+ << " -U - Use actual timestamps and uids/gids\n"
+ << " -X{32|64|32_64|any} - Specify which archive symbol tables "
+ "should be generated if they do not already exist (AIX OS only)\n";
}
static void printArHelp(StringRef ToolName) {
@@ -225,7 +227,8 @@ static bool DisplayMemberOffsets = false; ///< 'O' modifier
static bool CompareFullPath = false; ///< 'P' modifier
static bool OnlyUpdate = false; ///< 'u' modifier
static bool Verbose = false; ///< 'v' modifier
-static bool Symtab = true; ///< 's' modifier
+static SymtabWritingMode Symtab =
+ SymtabWritingMode::NormalSymtab; ///< 's' modifier
static bool Deterministic = true; ///< 'D' and 'U' modifiers
static bool Thin = false; ///< 'T' modifier
static bool AddLibrary = false; ///< 'L' modifier
@@ -371,11 +374,11 @@ static ArchiveOperation parseCommandLine() {
CompareFullPath = true;
break;
case 's':
- Symtab = true;
+ Symtab = SymtabWritingMode::NormalSymtab;
MaybeJustCreateSymTab = true;
break;
case 'S':
- Symtab = false;
+ Symtab = SymtabWritingMode::NoSymtab;
break;
case 'u':
OnlyUpdate = true;
@@ -1074,9 +1077,31 @@ static void createSymbolTable(object::Archive *OldArchive) {
// In summary, we only need to update the symbol table if we have none.
// This is actually very common because of broken build systems that think
// they have to run ranlib.
- if (OldArchive->hasSymbolTable())
- return;
+ if (OldArchive->hasSymbolTable()) {
+ if (OldArchive->kind() != object::Archive::K_AIXBIG)
+ return;
+ // For archives in the Big Archive format, the bit mode option specifies
+ // which symbol table to generate. The presence of a symbol table that does
+ // not match the specified bit mode does not prevent creation of the symbol
+ // table that has been requested.
+ if (OldArchive->kind() == object::Archive::K_AIXBIG) {
+ BigArchive *BigArc = dyn_cast<BigArchive>(OldArchive);
+ if (BigArc->has32BitGlobalSymtab() &&
+ Symtab == SymtabWritingMode::BigArchive32)
+ return;
+
+ if (BigArc->has64BitGlobalSymtab() &&
+ Symtab == SymtabWritingMode::BigArchive64)
+ return;
+
+ if (BigArc->has32BitGlobalSymtab() && BigArc->has64BitGlobalSymtab() &&
+ Symtab == SymtabWritingMode::NormalSymtab)
+ return;
+
+ Symtab = SymtabWritingMode::NormalSymtab;
+ }
+ }
if (OldArchive->isThin())
Thin = true;
performWriteOperation(CreateSymTab, OldArchive, nullptr, nullptr);
@@ -1389,6 +1414,8 @@ static int ar_main(int argc, char **argv) {
static int ranlib_main(int argc, char **argv) {
std::vector<StringRef> Archives;
+ bool HasAIXXOption = false;
+
for (int i = 1; i < argc; ++i) {
StringRef arg(argv[i]);
if (handleGenericOption(arg)) {
@@ -1406,6 +1433,28 @@ static int ranlib_main(int argc, char **argv) {
} else if (arg.front() == 'v') {
cl::PrintVersionMessage();
return 0;
+ } else if (arg.front() == 'X') {
+ if (object::Archive::getDefaultKindForHost() ==
+ object::Archive::K_AIXBIG) {
+ HasAIXXOption = true;
+ arg.consume_front("X");
+ const char *Xarg = arg.data();
+ if (Xarg[0] == '\0') {
+ if (argv[i + 1][0] != '-')
+ BitMode = getBitMode(argv[++i]);
+ else
+ BitMode = BitModeTy::Unknown;
+ } else
+ BitMode = getBitMode(arg.data());
+
+ if (BitMode == BitModeTy::Unknown)
+ fail("the specified object mode is not valid. Specify -X32, "
+ "-X64, -X32_64, or -Xany");
+ } else {
+ fail(Twine("-") + Twine(arg) +
+ " option not supported on non AIX OS");
+ }
+ break;
} else {
// TODO: GNU ranlib also supports a -t flag
fail("Invalid option: '-" + arg + "'");
@@ -1417,6 +1466,31 @@ static int ranlib_main(int argc, char **argv) {
}
}
+ if (object::Archive::getDefaultKindForHost() == object::Archive::K_AIXBIG) {
+ // If not specify -X option, get BitMode from enviorment variable
+ // "OBJECT_MODE" for AIX OS if specify.
+ if (!HasAIXXOption) {
+ if (char *EnvObjectMode = getenv("OBJECT_MODE")) {
+ BitMode = getBitMode(EnvObjectMode);
+ if (BitMode == BitModeTy::Unknown)
+ fail("the OBJECT_MODE environment variable has an invalid value. "
+ "OBJECT_MODE must be 32, 64, 32_64, or any");
+ }
+ }
+
+ switch (BitMode) {
+ case BitModeTy::Bit32:
+ Symtab = SymtabWritingMode::BigArchive32;
+ break;
+ case BitModeTy::Bit64:
+ Symtab = SymtabWritingMode::BigArchive64;
+ break;
+ default:
+ Symtab = SymtabWritingMode::NormalSymtab;
+ break;
+ }
+ }
+
for (StringRef Archive : Archives) {
ArchiveName = Archive.str();
performOperation(CreateSymTab);
diff --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
index 5e0ba139dd6bbf..9680cfa13cc5c2 100644
--- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
+++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
@@ -594,18 +594,17 @@ static Error createStaticLibrary(LLVMContext &LLVMCtx, const Config &C) {
if (NewMembers.size() == 1)
return writeArchive(OutputFile, NewMembers.begin()->second.getMembers(),
- /*WriteSymtab=*/true,
+ SymtabWritingMode::NormalSymtab,
/*Kind=*/object::Archive::K_DARWIN, C.Deterministic,
/*Thin=*/false);
SmallVector<OwningBinary<Archive>, 2> OutputBinaries;
for (const std::pair<const uint64_t, NewArchiveMemberList> &M : NewMembers) {
Expected<std::unique_ptr<MemoryBuffer>> OutputBufferOrErr =
- writeArchiveToBuffer(M.second.getMembers(),
- /*WriteSymtab=*/true,
- /*Kind=*/object::Archive::K_DARWIN,
- C.Deterministic,
- /*Thin=*/false);
+ writeArchiveToBuffer(
+ M.second.getMembers(), SymtabWritingMode::NormalSymtab,
+ /*Kind=*/object::Archive::K_DARWIN, C.Deterministic,
+ /*Thin=*/false);
if (!OutputBufferOrErr)
return OutputBufferOrErr.takeError();
std::unique_ptr<MemoryBuffer> &OutputBuffer = OutputBufferOrErr.get();
More information about the cfe-commits
mailing list