@@ -48,7 +48,7 @@ using namespace llvm;
4848using namespace llvm ::object;
4949
5050struct SymMap {
51- bool UseECMap;
51+ bool UseECMap = false ;
5252 std::map<std::string, uint16_t > Map;
5353 std::map<std::string, uint16_t > ECMap;
5454};
@@ -678,6 +678,25 @@ static bool isECObject(object::SymbolicFile &Obj) {
678678 return false ;
679679}
680680
681+ static bool isAnyArm64COFF (object::SymbolicFile &Obj) {
682+ if (Obj.isCOFF ())
683+ return COFF::isAnyArm64 (cast<COFFObjectFile>(&Obj)->getMachine ());
684+
685+ if (Obj.isCOFFImportFile ())
686+ return COFF::isAnyArm64 (cast<COFFImportFile>(&Obj)->getMachine ());
687+
688+ if (Obj.isIR ()) {
689+ Expected<std::string> TripleStr =
690+ getBitcodeTargetTriple (Obj.getMemoryBufferRef ());
691+ if (!TripleStr)
692+ return false ;
693+ Triple T (*TripleStr);
694+ return T.isOSWindows () && T.getArch () == Triple::aarch64;
695+ }
696+
697+ return false ;
698+ }
699+
681700bool isImportDescriptor (StringRef Name) {
682701 return Name.starts_with (ImportDescriptorPrefix) ||
683702 Name == StringRef{NullImportDescriptorSymbolName} ||
@@ -731,7 +750,8 @@ static Expected<std::vector<MemberData>>
731750computeMemberData (raw_ostream &StringTable, raw_ostream &SymNames,
732751 object::Archive::Kind Kind, bool Thin, bool Deterministic,
733752 SymtabWritingMode NeedSymbols, SymMap *SymMap,
734- LLVMContext &Context, ArrayRef<NewArchiveMember> NewMembers) {
753+ LLVMContext &Context, ArrayRef<NewArchiveMember> NewMembers,
754+ std::optional<bool > IsEC) {
735755 static char PaddingData[8 ] = {' \n ' , ' \n ' , ' \n ' , ' \n ' , ' \n ' , ' \n ' , ' \n ' , ' \n ' };
736756 uint64_t MemHeadPadSize = 0 ;
737757 uint64_t Pos =
@@ -807,6 +827,30 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
807827 }
808828 }
809829
830+ if (SymMap) {
831+ if (IsEC) {
832+ SymMap->UseECMap = *IsEC;
833+ } else {
834+ // When IsEC is not specified by the caller, use it when we have both
835+ // any ARM64 object (ARM64 or ARM64EC) and any EC object (ARM64EC or
836+ // AMD64). This may be a single ARM64EC object, but may also be separate
837+ // ARM64 and AMD64 objects.
838+ bool HaveArm64 = false , HaveEC = false ;
839+ for (std::unique_ptr<SymbolicFile> &SymFile : SymFiles) {
840+ if (!SymFile)
841+ continue ;
842+ if (!HaveArm64)
843+ HaveArm64 = isAnyArm64COFF (*SymFile);
844+ if (!HaveEC)
845+ HaveEC = isECObject (*SymFile);
846+ if (HaveArm64 && HaveEC) {
847+ SymMap->UseECMap = true ;
848+ break ;
849+ }
850+ }
851+ }
852+ }
853+
810854 // The big archive format needs to know the offset of the previous member
811855 // header.
812856 uint64_t PrevOffset = 0 ;
@@ -953,11 +997,10 @@ Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To) {
953997 return std::string (Relative);
954998}
955999
956- static Error writeArchiveToStream (raw_ostream &Out,
957- ArrayRef<NewArchiveMember> NewMembers,
958- SymtabWritingMode WriteSymtab,
959- object::Archive::Kind Kind,
960- bool Deterministic, bool Thin, bool IsEC) {
1000+ static Error
1001+ writeArchiveToStream (raw_ostream &Out, ArrayRef<NewArchiveMember> NewMembers,
1002+ SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
1003+ bool Deterministic, bool Thin, std::optional<bool > IsEC) {
9611004 assert ((!Thin || !isBSDLike (Kind)) && " Only the gnu format has a thin mode" );
9621005
9631006 SmallString<0 > SymNamesBuf;
@@ -977,10 +1020,9 @@ static Error writeArchiveToStream(raw_ostream &Out,
9771020 // reference to it, thus SymbolicFile should be destroyed first.
9781021 LLVMContext Context;
9791022
980- SymMap.UseECMap = IsEC;
9811023 Expected<std::vector<MemberData>> DataOrErr = computeMemberData (
9821024 StringTable, SymNames, Kind, Thin, Deterministic, WriteSymtab,
983- isCOFFArchive (Kind) ? &SymMap : nullptr , Context, NewMembers);
1025+ isCOFFArchive (Kind) ? &SymMap : nullptr , Context, NewMembers, IsEC );
9841026 if (Error E = DataOrErr.takeError ())
9851027 return E;
9861028 std::vector<MemberData> &Data = *DataOrErr;
@@ -1226,7 +1268,8 @@ static Error writeArchiveToStream(raw_ostream &Out,
12261268Error writeArchive (StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
12271269 SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
12281270 bool Deterministic, bool Thin,
1229- std::unique_ptr<MemoryBuffer> OldArchiveBuf, bool IsEC) {
1271+ std::unique_ptr<MemoryBuffer> OldArchiveBuf,
1272+ std::optional<bool > IsEC) {
12301273 Expected<sys::fs::TempFile> Temp =
12311274 sys::fs::TempFile::create (ArcName + " .temp-archive-%%%%%%%.a" );
12321275 if (!Temp)
@@ -1263,7 +1306,7 @@ writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers,
12631306 raw_svector_ostream ArchiveStream (ArchiveBufferVector);
12641307
12651308 if (Error E = writeArchiveToStream (ArchiveStream, NewMembers, WriteSymtab,
1266- Kind, Deterministic, Thin, false ))
1309+ Kind, Deterministic, Thin, std:: nullopt ))
12671310 return std::move (E);
12681311
12691312 return std::make_unique<SmallVectorMemoryBuffer>(
0 commit comments