@@ -48,7 +48,7 @@ using namespace llvm;
48
48
using namespace llvm ::object;
49
49
50
50
struct SymMap {
51
- bool UseECMap;
51
+ bool UseECMap = false ;
52
52
std::map<std::string, uint16_t > Map;
53
53
std::map<std::string, uint16_t > ECMap;
54
54
};
@@ -678,6 +678,25 @@ static bool isECObject(object::SymbolicFile &Obj) {
678
678
return false ;
679
679
}
680
680
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
+
681
700
bool isImportDescriptor (StringRef Name) {
682
701
return Name.starts_with (ImportDescriptorPrefix) ||
683
702
Name == StringRef{NullImportDescriptorSymbolName} ||
@@ -731,7 +750,8 @@ static Expected<std::vector<MemberData>>
731
750
computeMemberData (raw_ostream &StringTable, raw_ostream &SymNames,
732
751
object::Archive::Kind Kind, bool Thin, bool Deterministic,
733
752
SymtabWritingMode NeedSymbols, SymMap *SymMap,
734
- LLVMContext &Context, ArrayRef<NewArchiveMember> NewMembers) {
753
+ LLVMContext &Context, ArrayRef<NewArchiveMember> NewMembers,
754
+ std::optional<bool > IsEC) {
735
755
static char PaddingData[8 ] = {' \n ' , ' \n ' , ' \n ' , ' \n ' , ' \n ' , ' \n ' , ' \n ' , ' \n ' };
736
756
uint64_t MemHeadPadSize = 0 ;
737
757
uint64_t Pos =
@@ -807,6 +827,30 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
807
827
}
808
828
}
809
829
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 separated
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
+
810
854
// The big archive format needs to know the offset of the previous member
811
855
// header.
812
856
uint64_t PrevOffset = 0 ;
@@ -953,11 +997,10 @@ Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To) {
953
997
return std::string (Relative);
954
998
}
955
999
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) {
961
1004
assert ((!Thin || !isBSDLike (Kind)) && " Only the gnu format has a thin mode" );
962
1005
963
1006
SmallString<0 > SymNamesBuf;
@@ -977,10 +1020,9 @@ static Error writeArchiveToStream(raw_ostream &Out,
977
1020
// reference to it, thus SymbolicFile should be destroyed first.
978
1021
LLVMContext Context;
979
1022
980
- SymMap.UseECMap = IsEC;
981
1023
Expected<std::vector<MemberData>> DataOrErr = computeMemberData (
982
1024
StringTable, SymNames, Kind, Thin, Deterministic, WriteSymtab,
983
- isCOFFArchive (Kind) ? &SymMap : nullptr , Context, NewMembers);
1025
+ isCOFFArchive (Kind) ? &SymMap : nullptr , Context, NewMembers, IsEC );
984
1026
if (Error E = DataOrErr.takeError ())
985
1027
return E;
986
1028
std::vector<MemberData> &Data = *DataOrErr;
@@ -1226,7 +1268,8 @@ static Error writeArchiveToStream(raw_ostream &Out,
1226
1268
Error writeArchive (StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
1227
1269
SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
1228
1270
bool Deterministic, bool Thin,
1229
- std::unique_ptr<MemoryBuffer> OldArchiveBuf, bool IsEC) {
1271
+ std::unique_ptr<MemoryBuffer> OldArchiveBuf,
1272
+ std::optional<bool > IsEC) {
1230
1273
Expected<sys::fs::TempFile> Temp =
1231
1274
sys::fs::TempFile::create (ArcName + " .temp-archive-%%%%%%%.a" );
1232
1275
if (!Temp)
@@ -1263,7 +1306,7 @@ writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers,
1263
1306
raw_svector_ostream ArchiveStream (ArchiveBufferVector);
1264
1307
1265
1308
if (Error E = writeArchiveToStream (ArchiveStream, NewMembers, WriteSymtab,
1266
- Kind, Deterministic, Thin, false ))
1309
+ Kind, Deterministic, Thin, std::nullopt ))
1267
1310
return std::move (E);
1268
1311
1269
1312
return std::make_unique<SmallVectorMemoryBuffer>(
0 commit comments