DiggerLin updated this revision to Diff 522625.
DiggerLin marked 4 inline comments as done.
DiggerLin added a reviewer: stephenpeckham.
DiggerLin added a comment.
address Stephen's comment, thanks Stephen.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D142660/new/
https://reviews.llvm.org/D142660
Files:
clang/test/lit.cfg.py
llvm/include/llvm/Object/Archive.h
llvm/include/llvm/Object/ArchiveWriter.h
llvm/lib/Object/Archive.cpp
llvm/lib/Object/ArchiveWriter.cpp
llvm/test/lit.cfg.py
llvm/test/tools/llvm-ranlib/aix-X-option.test
llvm/tools/llvm-ar/llvm-ar.cpp
Index: llvm/tools/llvm-ar/llvm-ar.cpp
===================================================================
--- llvm/tools/llvm-ar/llvm-ar.cpp
+++ llvm/tools/llvm-ar/llvm-ar.cpp
@@ -76,7 +76,10 @@
<< " -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} - Specifies which archive symbol tables "
+ "should"
+ "be generated if they do not already exist (AIX OS only)\n";
}
static void printArHelp(StringRef ToolName) {
@@ -96,7 +99,7 @@
=windows - windows
--thin - create a thin archive
--version - print the version and exit
- -X{32|64|32_64|any} - object mode (only for AIX OS)
+ -X {32|64|32_64} - object mode (only for AIX OS)
@<file> - read options from <file>
OPERATIONS:
@@ -232,7 +235,7 @@
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 WriteSymTabType Symtab = true; ///< 's' modifier
static bool Deterministic = true; ///< 'D' and 'U' modifiers
static bool Thin = false; ///< 'T' modifier
static bool AddLibrary = false; ///< 'L' modifier
@@ -1081,9 +1084,25 @@
// 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;
+
+ // If BigArchive, if there is 32-bit globol symbol table, we still use -X64
+ // to generate the 64-bit global symbol table. Same as -X32 option.
+ if (OldArchive->kind() == object::Archive::K_AIXBIG) {
+ BigArchive *BigArc = dyn_cast<BigArchive>(OldArchive);
+ if (BigArc->has32BitGlobalSymtab() &&
+ Symtab.getBitMode() == WriteSymTabType::BitMode::Bit32)
+ return;
+ if (BigArc->has64BitGlobalSymtab() &&
+ Symtab.getBitMode() == WriteSymTabType::BitMode::Bit64)
+ return;
+
+ Symtab.setBitMode(WriteSymTabType::BitMode::Both);
+ }
+ }
if (OldArchive->isThin())
Thin = true;
performWriteOperation(CreateSymTab, OldArchive, nullptr, nullptr);
@@ -1257,6 +1276,7 @@
static BitModeTy getBitMode(const char *RawBitMode) {
return StringSwitch<BitModeTy>(RawBitMode)
+ .Case("", BitModeTy::Bit32)
.Case("32", BitModeTy::Bit32)
.Case("64", BitModeTy::Bit64)
.Case("32_64", BitModeTy::Bit32_64)
@@ -1396,6 +1416,8 @@
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)) {
@@ -1413,6 +1435,27 @@
} 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')
+ BitMode = BitModeTy::Unknown;
+ else
+ BitMode = getBitMode(arg.data());
+
+ // -X option in ranlib do not accept "any"
+ if (BitMode == BitModeTy::Unknown || BitMode == BitModeTy::Any)
+ fail(
+ Twine("The specified object mode is not valid. Specify -X32, "
+ "-X64, or -X32_64."));
+ } 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 + "'");
@@ -1424,6 +1467,30 @@
}
}
+ 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) {
+ BitMode = getBitMode(getenv("OBJECT_MODE"));
+ // -X option in ranlib do not accept "any"
+ if (BitMode == BitModeTy::Any || BitMode == BitModeTy::Unknown)
+ fail("The OBJECT_MODE environment variable has an invalid setting. "
+ "OBJECT_MODE must be 32, 64, or 32_64.");
+ }
+
+ switch (BitMode) {
+ case BitModeTy::Bit32:
+ Symtab.setBitMode(WriteSymTabType::BitMode::Bit32);
+ break;
+ case BitModeTy::Bit64:
+ Symtab.setBitMode(WriteSymTabType::BitMode::Bit64);
+ break;
+ default:
+ Symtab = true;
+ break;
+ }
+ }
+
for (StringRef Archive : Archives) {
ArchiveName = Archive.str();
performOperation(CreateSymTab);
Index: llvm/test/tools/llvm-ranlib/aix-X-option.test
===================================================================
--- /dev/null
+++ llvm/test/tools/llvm-ranlib/aix-X-option.test
@@ -0,0 +1,136 @@
+## 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 OBJECT_MODE environment variable when adding symbol table
+# RUN: env OBJECT_MODE= llvm-ranlib 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,GL64 %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,GL32 %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.a
+# RUN: cp t_all.a t_X64.a
+# RUN: cp t_all.a t_X32_64.a
+
+## Test -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,GL64 %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,GL32 %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.a
+# RUN: cp t_all.a t_X64.a
+
+## Test -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,GL64 %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,GL32 %s
+
+## Test invalid -X option and invalid OBJECT_MODE
+# RUN: not env OBJECT_MODE=any llvm-ranlib t_X64.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 -Xany 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
+
+#GLOB32: var_0x1DF in t32_1.o
+#GLOB32-NEXT: array_0x1DF in t32_1.o
+#GLOB32-NEXT: func_0x1DF in t32_2.o
+#GLOB32-NEXT: bar_0x1DF in t32_2.o
+
+#GL64-NOT: var_0x1F7 in t64_1.o
+#GL64-NOT: array_0x1F7 in t64_1.o
+#GL64-NOT: func_0x1F7 in t64_2.o
+#GL64-NOT: bar_0x1F7 in t64_2.o
+
+#GLOB64: var_0x1F7 in t64_1.o
+#GLOB64-NEXT: array_0x1F7 in t64_1.o
+#GLOB64-NEXT: func_0x1F7 in t64_2.o
+#GLOB64-NEXT: bar_0x1F7 in t64_2.o
+
+#GL32-NOT: var_0x1DF in t32_1.o
+#GL32-NOT: array_0x1DF in t32_1.o
+#GL32-NOT: func_0x1DF in t32_2.o
+#GL32-NOT: bar_0x1DF in t32_2.o
+
+#GLOB1: var_0x1DF in t32_1.o
+#GLOB1-NEXT: array_0x1DF in t32_1.o
+#GLOB1-NEXT: var_0x1F7 in t64_1.o
+#GLOB1-NEXT: array_0x1F7 in t64_1.o
+
+#INVALID-OBJECT-MODE: error: The OBJECT_MODE environment variable has an invalid setting. OBJECT_MODE must be 32, 64, or 32_64.
+#INVALID-X-OPTION: error: The specified object mode is not valid. Specify -X32, -X64, or -X32_64.
+
+--- !XCOFF
+FileHeader:
+ MagicNumber: [[FLAG]]
+Sections:
+ - Name: .data
+ Flags: [ STYP_DATA ]
+Symbols:
+ - Name: var_[[FLAG]]
+ Section: .data
+ Type: 0x4000
+ StorageClass: C_EXT
+ AuxEntries:
+ - Type: AUX_CSECT
+ SymbolAlignmentAndType: 0x09
+ StorageMappingClass: XMC_RW
+ - Name: array_[[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: func_[[FLAG]]
+ Section: .text
+ Type: 0x4000
+ StorageClass: C_EXT
+ AuxEntries:
+ - Type: AUX_CSECT
+ SymbolAlignmentAndType: 0x09
+ StorageMappingClass: XMC_PR
+ - Name: bar_[[FLAG]]
+ Section: .text
+ Type: 0x4000
+ StorageClass: C_EXT
+ AuxEntries:
+ - Type: AUX_CSECT
+ SymbolAlignmentAndType: 0x09
+ StorageMappingClass: XMC_PR
Index: llvm/test/lit.cfg.py
===================================================================
--- llvm/test/lit.cfg.py
+++ llvm/test/lit.cfg.py
@@ -501,6 +501,6 @@
# 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' by default on AIX OS.
+# "OBJECT_MODE" to '32_64' by default on AIX OS.
if 'system-aix' in config.available_features:
- config.environment['OBJECT_MODE'] = 'any'
+ config.environment['OBJECT_MODE'] = '32_64'
Index: llvm/lib/Object/ArchiveWriter.cpp
===================================================================
--- llvm/lib/Object/ArchiveWriter.cpp
+++ llvm/lib/Object/ArchiveWriter.cpp
@@ -527,7 +527,8 @@
static Expected<std::vector<MemberData>>
computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
object::Archive::Kind Kind, bool Thin, bool Deterministic,
- bool NeedSymbols, ArrayRef<NewArchiveMember> NewMembers) {
+ WriteSymTabType NeedSymbols,
+ ArrayRef<NewArchiveMember> NewMembers) {
static char PaddingData[8] = {'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'};
uint64_t Pos =
@@ -703,7 +704,8 @@
static Error writeArchiveToStream(raw_ostream &Out,
ArrayRef<NewArchiveMember> NewMembers,
- bool WriteSymtab, object::Archive::Kind Kind,
+ WriteSymTabType WriteSymtab,
+ object::Archive::Kind Kind,
bool Deterministic, bool Thin) {
assert((!Thin || !isBSDLike(Kind)) && "Only the gnu format has a thin mode");
@@ -850,14 +852,18 @@
// 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)
+ (WriteSymtab &&
+ (WriteSymtab.getBitMode() != WriteSymTabType::BitMode::Bit64) &&
+ NumSyms32 > 0)
? LastMemberEndOffset +
alignTo(sizeof(object::BigArMemHdrType) + MemberTableSize, 2)
: 0;
uint64_t GlobalSymbolOffset64 = 0;
uint64_t NumSyms64 = NumSyms - NumSyms32;
- if (WriteSymtab && NumSyms64 > 0) {
+ if (WriteSymtab &&
+ (WriteSymtab.getBitMode() != WriteSymTabType::BitMode::Bit32) &&
+ NumSyms64 > 0) {
if (GlobalSymbolOffset == 0)
GlobalSymbolOffset64 =
LastMemberEndOffset +
@@ -936,7 +942,7 @@
}
Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
- bool WriteSymtab, object::Archive::Kind Kind,
+ WriteSymTabType WriteSymtab, object::Archive::Kind Kind,
bool Deterministic, bool Thin,
std::unique_ptr<MemoryBuffer> OldArchiveBuf) {
Expected<sys::fs::TempFile> Temp =
@@ -968,9 +974,9 @@
}
Expected<std::unique_ptr<MemoryBuffer>>
-writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers, bool WriteSymtab,
- object::Archive::Kind Kind, bool Deterministic,
- bool Thin) {
+writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers,
+ WriteSymTabType WriteSymtab, object::Archive::Kind Kind,
+ bool Deterministic, bool Thin) {
SmallVector<char, 0> ArchiveBufferVector;
raw_svector_ostream ArchiveStream(ArchiveBufferVector);
Index: llvm/lib/Object/Archive.cpp
===================================================================
--- llvm/lib/Object/Archive.cpp
+++ llvm/lib/Object/Archive.cpp
@@ -1267,6 +1267,8 @@
GlobSym32Size, "32-bit");
if (Err)
return;
+
+ Has32BitGlobalSymtab = true;
}
if (GlobSym64Offset) {
@@ -1274,6 +1276,8 @@
GlobSym64Size, "64-bit");
if (Err)
return;
+
+ Has64BitGlobalSymtab = true;
}
SmallVector<GlobalSymTblInfo> SymTblInfos;
Index: llvm/include/llvm/Object/ArchiveWriter.h
===================================================================
--- llvm/include/llvm/Object/ArchiveWriter.h
+++ llvm/include/llvm/Object/ArchiveWriter.h
@@ -40,16 +40,36 @@
Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To);
+class WriteSymTabType {
+public:
+ enum BitMode {
+ None, // Not write Symbol table.
+ Both, // Write both 32-bit and 64-bit symbol table.
+ Bit32, // Only write the 32-bit symbol table.
+ Bit64 // Only write the 64-bit symbol table.
+ };
+
+ WriteSymTabType(bool PrintSym) { Value = PrintSym ? Both : None; }
+ void operator=(bool PrintSym) { Value = PrintSym ? Both : None; }
+ operator bool() { return Value != None; }
+ void setBitMode(BitMode BM) { Value = BM; }
+ BitMode getBitMode() { return Value; }
+
+private:
+ BitMode Value;
+};
+
Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
- bool WriteSymtab, object::Archive::Kind Kind,
+ WriteSymTabType WriteSymtab, object::Archive::Kind Kind,
bool Deterministic, bool Thin,
std::unique_ptr<MemoryBuffer> OldArchiveBuf = nullptr);
// 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,
+ WriteSymTabType WriteSymtab, object::Archive::Kind Kind,
+ bool Deterministic, bool Thin);
}
#endif
Index: llvm/include/llvm/Object/Archive.h
===================================================================
--- llvm/include/llvm/Object/Archive.h
+++ llvm/include/llvm/Object/Archive.h
@@ -406,6 +406,8 @@
uint64_t FirstChildOffset = 0;
uint64_t LastChildOffset = 0;
std::string MergedGloSymTblBuf;
+ bool Has32BitGlobalSymtab = false;
+ bool Has64BitGlobalSymtab = false;
public:
BigArchive(MemoryBufferRef Source, Error &Err);
@@ -414,6 +416,9 @@
bool isEmpty() const override {
return Data.getBufferSize() == sizeof(FixLenHdr);
};
+
+ bool has32BitGlobalSymtab() { return Has32BitGlobalSymtab; }
+ bool has64BitGlobalSymtab() { return Has64BitGlobalSymtab; }
};
} // end namespace object
Index: clang/test/lit.cfg.py
===================================================================
--- clang/test/lit.cfg.py
+++ clang/test/lit.cfg.py
@@ -282,15 +282,15 @@
elif platform.system() == 'AIX':
config.environment['AIXTHREAD_STK'] = '4194304'
-# The llvm-nm tool supports an environment variable "OBJECT_MODE" on AIX OS, which
+# Some tool 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 '32_64' by default on AIX OS.
if 'system-aix' in config.available_features:
- config.substitutions.append(('llvm-nm', 'env OBJECT_MODE=any llvm-nm'))
+ config.environment['OBJECT_MODE'] = '32_64'
# It is not realistically possible to account for all options that could
# possibly be present in system and user configuration files, so disable
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits