Skip to content

Commit f740bcb

Browse files
committed
[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@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
1 parent 8f6a1a0 commit f740bcb

File tree

15 files changed

+293
-57
lines changed

15 files changed

+293
-57
lines changed

clang/lib/Driver/OffloadBundler.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -1265,8 +1265,9 @@ Error OffloadBundler::UnbundleArchive() {
12651265
OutputArchivesMap.find(Target);
12661266
if (CurArchiveMembers != OutputArchivesMap.end()) {
12671267
if (Error WriteErr = writeArchive(FileName, CurArchiveMembers->getValue(),
1268-
true, getDefaultArchiveKindForHost(),
1269-
true, false, nullptr))
1268+
SymtabWritingMode::NormalSymtab,
1269+
getDefaultArchiveKindForHost(), true,
1270+
false, nullptr))
12701271
return WriteErr;
12711272
} else if (!BundlerConfig.AllowMissingBundles) {
12721273
std::string ErrMsg =
@@ -1280,9 +1281,9 @@ Error OffloadBundler::UnbundleArchive() {
12801281
// the missing input file.
12811282
std::vector<llvm::NewArchiveMember> EmptyArchive;
12821283
EmptyArchive.clear();
1283-
if (Error WriteErr = writeArchive(FileName, EmptyArchive, true,
1284-
getDefaultArchiveKindForHost(), true,
1285-
false, nullptr))
1284+
if (Error WriteErr = writeArchive(
1285+
FileName, EmptyArchive, SymtabWritingMode::NormalSymtab,
1286+
getDefaultArchiveKindForHost(), true, false, nullptr))
12861287
return WriteErr;
12871288
}
12881289
}

clang/test/lit.cfg.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -380,16 +380,15 @@ def exclude_unsupported_files_for_aix(dirname):
380380
elif platform.system() == "AIX":
381381
config.environment["AIXTHREAD_STK"] = "4194304"
382382

383-
# The llvm-nm tool supports an environment variable "OBJECT_MODE" on AIX OS, which
383+
# Some tools support an environment variable "OBJECT_MODE" on AIX OS, which
384384
# controls the kind of objects they will support. If there is no "OBJECT_MODE"
385385
# environment variable specified, the default behaviour is to support 32-bit
386386
# objects only. In order to not affect most test cases, which expect to support
387387
# 32-bit and 64-bit objects by default, set the environment variable
388-
# "OBJECT_MODE" to 'any' for llvm-nm on AIX OS.
388+
# "OBJECT_MODE" to "any" by default on AIX OS.
389389

390390
if "system-aix" in config.available_features:
391-
config.substitutions.append(("llvm-nm", "env OBJECT_MODE=any llvm-nm"))
392-
config.substitutions.append(("llvm-ar", "env OBJECT_MODE=any llvm-ar"))
391+
config.environment["OBJECT_MODE"] = "any"
393392

394393
# It is not realistically possible to account for all options that could
395394
# possibly be present in system and user configuration files, so disable

clang/tools/clang-offload-packager/ClangOffloadPackager.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,9 @@ static Error unbundleImages() {
192192
Binary->getImage(),
193193
Binary->getMemoryBufferRef().getBufferIdentifier()));
194194

195-
if (Error E = writeArchive(Args["file"], Members, true,
196-
Archive::getDefaultKindForHost(), true, false,
197-
nullptr))
195+
if (Error E = writeArchive(
196+
Args["file"], Members, SymtabWritingMode::NormalSymtab,
197+
Archive::getDefaultKindForHost(), true, false, nullptr))
198198
return E;
199199
} else if (Args.count("file")) {
200200
if (Extracted.size() > 1)

llvm/include/llvm/Object/Archive.h

+5
Original file line numberDiff line numberDiff line change
@@ -411,12 +411,17 @@ class BigArchive : public Archive {
411411
uint64_t FirstChildOffset = 0;
412412
uint64_t LastChildOffset = 0;
413413
std::string MergedGlobalSymtabBuf;
414+
bool Has32BitGlobalSymtab = false;
415+
bool Has64BitGlobalSymtab = false;
414416

415417
public:
416418
BigArchive(MemoryBufferRef Source, Error &Err);
417419
uint64_t getFirstChildOffset() const override { return FirstChildOffset; }
418420
uint64_t getLastChildOffset() const { return LastChildOffset; }
419421
bool isEmpty() const override { return getFirstChildOffset() == 0; }
422+
423+
bool has32BitGlobalSymtab() { return Has32BitGlobalSymtab; }
424+
bool has64BitGlobalSymtab() { return Has64BitGlobalSymtab; }
420425
};
421426

422427
} // end namespace object

llvm/include/llvm/Object/ArchiveWriter.h

+12-3
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,26 @@ struct NewArchiveMember {
4040

4141
Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To);
4242

43+
enum class SymtabWritingMode {
44+
NoSymtab, // Do not write symbol table.
45+
NormalSymtab, // Write symbol table. For the Big Archive format, write both
46+
// 32-bit and 64-bit symbol tables.
47+
BigArchive32, // Only write the 32-bit symbol table.
48+
BigArchive64 // Only write the 64-bit symbol table.
49+
};
50+
4351
Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
44-
bool WriteSymtab, object::Archive::Kind Kind,
52+
SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
4553
bool Deterministic, bool Thin,
4654
std::unique_ptr<MemoryBuffer> OldArchiveBuf = nullptr,
4755
bool IsEC = false);
4856

4957
// writeArchiveToBuffer is similar to writeArchive but returns the Archive in a
5058
// buffer instead of writing it out to a file.
5159
Expected<std::unique_ptr<MemoryBuffer>>
52-
writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers, bool WriteSymtab,
53-
object::Archive::Kind Kind, bool Deterministic, bool Thin);
60+
writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers,
61+
SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
62+
bool Deterministic, bool Thin);
5463
}
5564

5665
#endif

llvm/lib/ObjCopy/Archive.cpp

+7-4
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@ createNewArchiveMembers(const MultiFormatConfig &Config, const Archive &Ar) {
6060
// For thin archives it writes the archive file itself as well as its members.
6161
static Error deepWriteArchive(StringRef ArcName,
6262
ArrayRef<NewArchiveMember> NewMembers,
63-
bool WriteSymtab, object::Archive::Kind Kind,
64-
bool Deterministic, bool Thin) {
63+
SymtabWritingMode WriteSymtab,
64+
object::Archive::Kind Kind, bool Deterministic,
65+
bool Thin) {
6566
if (Kind == object::Archive::K_BSD && !NewMembers.empty() &&
6667
NewMembers.front().detectKindFromObject() == object::Archive::K_DARWIN)
6768
Kind = object::Archive::K_DARWIN;
@@ -102,8 +103,10 @@ Error executeObjcopyOnArchive(const MultiFormatConfig &Config,
102103
return NewArchiveMembersOrErr.takeError();
103104
const CommonConfig &CommonConfig = Config.getCommonConfig();
104105
return deepWriteArchive(CommonConfig.OutputFilename, *NewArchiveMembersOrErr,
105-
Ar.hasSymbolTable(), Ar.kind(),
106-
CommonConfig.DeterministicArchives, Ar.isThin());
106+
Ar.hasSymbolTable() ? SymtabWritingMode::NormalSymtab
107+
: SymtabWritingMode::NoSymtab,
108+
Ar.kind(), CommonConfig.DeterministicArchives,
109+
Ar.isThin());
107110
}
108111

109112
} // end namespace objcopy

llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -490,10 +490,12 @@ Error objcopy::macho::executeObjcopyOnMachOUniversalBinary(
490490
if (Kind == object::Archive::K_BSD)
491491
Kind = object::Archive::K_DARWIN;
492492
Expected<std::unique_ptr<MemoryBuffer>> OutputBufferOrErr =
493-
writeArchiveToBuffer(*NewArchiveMembersOrErr,
494-
(*ArOrErr)->hasSymbolTable(), Kind,
495-
Config.getCommonConfig().DeterministicArchives,
496-
(*ArOrErr)->isThin());
493+
writeArchiveToBuffer(
494+
*NewArchiveMembersOrErr,
495+
(*ArOrErr)->hasSymbolTable() ? SymtabWritingMode::NormalSymtab
496+
: SymtabWritingMode::NoSymtab,
497+
Kind, Config.getCommonConfig().DeterministicArchives,
498+
(*ArOrErr)->isThin());
497499
if (!OutputBufferOrErr)
498500
return OutputBufferOrErr.takeError();
499501
Expected<std::unique_ptr<Binary>> BinaryOrErr =

llvm/lib/Object/Archive.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -1392,6 +1392,8 @@ BigArchive::BigArchive(MemoryBufferRef Source, Error &Err)
13921392
GlobSymtab32Loc, GlobSymtab32Size, "32-bit");
13931393
if (Err)
13941394
return;
1395+
1396+
Has32BitGlobalSymtab = true;
13951397
}
13961398

13971399
if (GlobSymtab64Offset) {
@@ -1400,6 +1402,8 @@ BigArchive::BigArchive(MemoryBufferRef Source, Error &Err)
14001402
GlobSymtab64Loc, GlobSymtab64Size, "64-bit");
14011403
if (Err)
14021404
return;
1405+
1406+
Has64BitGlobalSymtab = true;
14031407
}
14041408

14051409
SmallVector<GlobalSymtabInfo> SymtabInfos;

llvm/lib/Object/ArchiveWriter.cpp

+21-15
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ getSymbols(MemoryBufferRef Buf, uint16_t Index, raw_ostream &SymNames,
680680
static Expected<std::vector<MemberData>>
681681
computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
682682
object::Archive::Kind Kind, bool Thin, bool Deterministic,
683-
bool NeedSymbols, SymMap *SymMap,
683+
SymtabWritingMode NeedSymbols, SymMap *SymMap,
684684
ArrayRef<NewArchiveMember> NewMembers) {
685685
static char PaddingData[8] = {'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'};
686686

@@ -796,7 +796,7 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
796796
Out.flush();
797797

798798
std::vector<unsigned> Symbols;
799-
if (NeedSymbols) {
799+
if (NeedSymbols != SymtabWritingMode::NoSymtab) {
800800
Expected<std::vector<unsigned>> SymbolsOrErr =
801801
getSymbols(Buf, Index, SymNames, SymMap, HasObject);
802802
if (!SymbolsOrErr)
@@ -860,7 +860,8 @@ Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To) {
860860

861861
static Error writeArchiveToStream(raw_ostream &Out,
862862
ArrayRef<NewArchiveMember> NewMembers,
863-
bool WriteSymtab, object::Archive::Kind Kind,
863+
SymtabWritingMode WriteSymtab,
864+
object::Archive::Kind Kind,
864865
bool Deterministic, bool Thin, bool IsEC) {
865866
assert((!Thin || !isBSDLike(Kind)) && "Only the gnu format has a thin mode");
866867

@@ -897,6 +898,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
897898
uint64_t LastMemberHeaderOffset = 0;
898899
uint64_t NumSyms = 0;
899900
uint64_t NumSyms32 = 0; // Store symbol number of 32-bit member files.
901+
bool ShouldWriteSymtab = WriteSymtab != SymtabWritingMode::NoSymtab;
900902

901903
for (const auto &M : Data) {
902904
// Record the start of the member's offset
@@ -910,7 +912,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
910912
// symbols; the second global symbol table does the same for 64-bit file
911913
// members. As a big archive can have both 32-bit and 64-bit file members,
912914
// we need to know the number of symbols in each symbol table individually.
913-
if (isAIXBigArchive(Kind) && WriteSymtab) {
915+
if (isAIXBigArchive(Kind) && ShouldWriteSymtab) {
914916
Expected<bool> Is64BitOrErr = is64BitSymbolicFile(M.Data);
915917
if (Error E = Is64BitOrErr.takeError())
916918
return E;
@@ -924,7 +926,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
924926

925927
// The symbol table is put at the end of the big archive file. The symbol
926928
// table is at the start of the archive file for other archive formats.
927-
if (WriteSymtab && !is64BitKind(Kind)) {
929+
if (ShouldWriteSymtab && !is64BitKind(Kind)) {
928930
// We assume 32-bit offsets to see if 32-bit symbols are possible or not.
929931
HeadersSize = computeHeadersSize(Kind, Data.size(), StringTableSize,
930932
NumSyms, SymNamesBuf.size(),
@@ -962,7 +964,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
962964
Out << "!<arch>\n";
963965

964966
if (!isAIXBigArchive(Kind)) {
965-
if (WriteSymtab) {
967+
if (ShouldWriteSymtab) {
966968
if (!HeadersSize)
967969
HeadersSize = computeHeadersSize(
968970
Kind, Data.size(), StringTableSize, NumSyms, SymNamesBuf.size(),
@@ -978,7 +980,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
978980
Out << StringTableMember.Header << StringTableMember.Data
979981
<< StringTableMember.Padding;
980982

981-
if (WriteSymtab && SymMap.ECMap.size())
983+
if (ShouldWriteSymtab && SymMap.ECMap.size())
982984
writeECSymbols(Out, Kind, Deterministic, Data, SymMap);
983985

984986
for (const MemberData &M : Data)
@@ -1017,7 +1019,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
10171019
raw_svector_ostream SymNames32(SymNamesBuf32);
10181020
raw_svector_ostream SymNames64(SymNamesBuf64);
10191021

1020-
if (WriteSymtab && NumSyms)
1022+
if (ShouldWriteSymtab && NumSyms)
10211023
// Generate the symbol names for the members.
10221024
for (const NewArchiveMember &M : NewMembers) {
10231025
MemoryBufferRef Buf = M.Buf->getMemBufferRef();
@@ -1041,11 +1043,15 @@ static Error writeArchiveToStream(raw_ostream &Out,
10411043
// the offset to the 32-bit global symbol table, and the 'GlobSym64Offset'
10421044
// contains the offset to the 64-bit global symbol table.
10431045
uint64_t GlobalSymbolOffset =
1044-
(WriteSymtab && NumSyms32 > 0) ? MemberTableEndOffset : 0;
1046+
(ShouldWriteSymtab &&
1047+
(WriteSymtab != SymtabWritingMode::BigArchive64) && NumSyms32 > 0)
1048+
? MemberTableEndOffset
1049+
: 0;
10451050

10461051
uint64_t GlobalSymbolOffset64 = 0;
10471052
uint64_t NumSyms64 = NumSyms - NumSyms32;
1048-
if (WriteSymtab && NumSyms64 > 0) {
1053+
if (ShouldWriteSymtab && (WriteSymtab != SymtabWritingMode::BigArchive32) &&
1054+
NumSyms64 > 0) {
10491055
if (GlobalSymbolOffset == 0)
10501056
GlobalSymbolOffset64 = MemberTableEndOffset;
10511057
else
@@ -1095,7 +1101,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
10951101
Out << '\0'; // Name table must be tail padded to an even number of
10961102
// bytes.
10971103

1098-
if (WriteSymtab) {
1104+
if (ShouldWriteSymtab) {
10991105
// Write global symbol table for 32-bit file members.
11001106
if (GlobalSymbolOffset) {
11011107
writeSymbolTable(Out, Kind, Deterministic, Data, SymNamesBuf32,
@@ -1121,7 +1127,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
11211127
}
11221128

11231129
Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
1124-
bool WriteSymtab, object::Archive::Kind Kind,
1130+
SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
11251131
bool Deterministic, bool Thin,
11261132
std::unique_ptr<MemoryBuffer> OldArchiveBuf, bool IsEC) {
11271133
Expected<sys::fs::TempFile> Temp =
@@ -1153,9 +1159,9 @@ Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
11531159
}
11541160

11551161
Expected<std::unique_ptr<MemoryBuffer>>
1156-
writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers, bool WriteSymtab,
1157-
object::Archive::Kind Kind, bool Deterministic,
1158-
bool Thin) {
1162+
writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers,
1163+
SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
1164+
bool Deterministic, bool Thin) {
11591165
SmallVector<char, 0> ArchiveBufferVector;
11601166
raw_svector_ostream ArchiveStream(ArchiveBufferVector);
11611167

llvm/lib/Object/COFFImportFile.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,
610610
OF.createShortImport(*Name, E.Ordinal, ImportType, NameType));
611611
}
612612

613-
return writeArchive(Path, Members, /*WriteSymtab*/ true,
613+
return writeArchive(Path, Members, SymtabWritingMode::NormalSymtab,
614614
MinGW ? object::Archive::K_GNU : object::Archive::K_COFF,
615615
/*Deterministic*/ true, /*Thin*/ false);
616616
}

llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp

+4-6
Original file line numberDiff line numberDiff line change
@@ -482,12 +482,10 @@ int llvm::libDriverMain(ArrayRef<const char *> ArgsArr) {
482482
std::reverse(Members.begin(), Members.end());
483483

484484
bool Thin = Args.hasArg(OPT_llvmlibthin);
485-
if (Error E =
486-
writeArchive(OutputPath, Members,
487-
/*WriteSymtab=*/true,
488-
Thin ? object::Archive::K_GNU : object::Archive::K_COFF,
489-
/*Deterministic*/ true, Thin, nullptr,
490-
COFF::isArm64EC(LibMachine))) {
485+
if (Error E = writeArchive(
486+
OutputPath, Members, SymtabWritingMode::NormalSymtab,
487+
Thin ? object::Archive::K_GNU : object::Archive::K_COFF,
488+
/*Deterministic=*/true, Thin, nullptr, COFF::isArm64EC(LibMachine))) {
491489
handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
492490
llvm::errs() << OutputPath << ": " << EI.message() << "\n";
493491
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# UNSUPPORTED: system-aix
2+
## Test the -X option is not supported on non-AIX os.
3+
4+
# RUN: not llvm-ranlib -X32 2>&1 | FileCheck --implicit-check-not="error:" --check-prefix=INVALID-X-OPTION %s
5+
6+
# INVALID-X-OPTION: error: -X32 option not supported on non AIX OS

0 commit comments

Comments
 (0)