45
45
using namespace llvm ;
46
46
47
47
struct SymMap {
48
+ bool UseECMap;
48
49
std::map<std::string, uint16_t > Map;
50
+ std::map<std::string, uint16_t > ECMap;
49
51
};
50
52
51
53
NewArchiveMember::NewArchiveMember (MemoryBufferRef BufRef)
@@ -414,6 +416,20 @@ static uint64_t computeSymbolMapSize(uint64_t NumObj, SymMap &SymMap,
414
416
return Size;
415
417
}
416
418
419
+ static uint64_t computeECSymbolsSize (SymMap &SymMap,
420
+ uint32_t *Padding = nullptr ) {
421
+ uint64_t Size = sizeof (uint32_t ); // Number of symbols
422
+
423
+ for (auto S : SymMap.ECMap )
424
+ Size += sizeof (uint16_t ) + S.first .length () + 1 ;
425
+
426
+ uint32_t Pad = offsetToAlignment (Size, Align (2 ));
427
+ Size += Pad;
428
+ if (Padding)
429
+ *Padding = Pad;
430
+ return Size;
431
+ }
432
+
417
433
static void writeSymbolTableHeader (raw_ostream &Out, object::Archive::Kind Kind,
418
434
bool Deterministic, uint64_t Size,
419
435
uint64_t PrevMemberOffset = 0 ) {
@@ -446,8 +462,11 @@ static uint64_t computeHeadersSize(object::Archive::Kind Kind,
446
462
uint32_t HeaderSize = computeSymbolTableHeaderSize ();
447
463
uint64_t Size = strlen (" !<arch>\n " ) + HeaderSize + SymtabSize;
448
464
449
- if (SymMap)
465
+ if (SymMap) {
450
466
Size += HeaderSize + computeSymbolMapSize (NumMembers, *SymMap);
467
+ if (SymMap->ECMap .size ())
468
+ Size += HeaderSize + computeECSymbolsSize (*SymMap);
469
+ }
451
470
452
471
return Size + StringMemberSize;
453
472
}
@@ -521,6 +540,41 @@ static void writeSymbolMap(raw_ostream &Out, object::Archive::Kind Kind,
521
540
Out.write (uint8_t (0 ));
522
541
}
523
542
543
+ static void writeECSymbols (raw_ostream &Out, object::Archive::Kind Kind,
544
+ bool Deterministic, ArrayRef<MemberData> Members,
545
+ SymMap &SymMap) {
546
+ uint32_t Pad;
547
+ uint64_t Size = computeECSymbolsSize (SymMap, &Pad);
548
+ printGNUSmallMemberHeader (Out, " /<ECSYMBOLS>" , now (Deterministic), 0 , 0 , 0 ,
549
+ Size);
550
+
551
+ printLE<uint32_t >(Out, SymMap.ECMap .size ());
552
+
553
+ for (auto S : SymMap.ECMap )
554
+ printLE (Out, S.second );
555
+ for (auto S : SymMap.ECMap )
556
+ Out << S.first << ' \0 ' ;
557
+ while (Pad--)
558
+ Out.write (uint8_t (0 ));
559
+ }
560
+
561
+ static bool isECObject (object::SymbolicFile &Obj) {
562
+ if (Obj.isCOFF ())
563
+ return cast<llvm::object::COFFObjectFile>(&Obj)->getMachine () !=
564
+ COFF::IMAGE_FILE_MACHINE_ARM64;
565
+
566
+ if (Obj.isIR ()) {
567
+ Expected<std::string> TripleStr =
568
+ getBitcodeTargetTriple (Obj.getMemoryBufferRef ());
569
+ if (!TripleStr)
570
+ return false ;
571
+ Triple T (*TripleStr);
572
+ return T.isWindowsArm64EC () || T.getArch () == Triple::x86_64;
573
+ }
574
+
575
+ return false ;
576
+ }
577
+
524
578
static Expected<std::vector<unsigned >>
525
579
getSymbols (MemoryBufferRef Buf, uint16_t Index, raw_ostream &SymNames,
526
580
SymMap *SymMap, bool &HasObject) {
@@ -548,20 +602,25 @@ getSymbols(MemoryBufferRef Buf, uint16_t Index, raw_ostream &SymNames,
548
602
Obj = std::move (*ObjOrErr);
549
603
}
550
604
605
+ std::map<std::string, uint16_t > *Map = nullptr ;
606
+ if (SymMap)
607
+ Map = SymMap->UseECMap && isECObject (*Obj) ? &SymMap->ECMap : &SymMap->Map ;
551
608
HasObject = true ;
552
609
for (const object::BasicSymbolRef &S : Obj->symbols ()) {
553
610
if (!isArchiveSymbol (S))
554
611
continue ;
555
- if (SymMap ) {
612
+ if (Map ) {
556
613
std::string Name;
557
614
raw_string_ostream NameStream (Name);
558
615
if (Error E = S.printName (NameStream))
559
616
return std::move (E);
560
- if (SymMap-> Map . find (Name) != SymMap-> Map . end ())
617
+ if (Map-> find (Name) != Map-> end ())
561
618
continue ; // ignore duplicated symbol
562
- SymMap->Map [Name] = Index;
563
- Ret.push_back (SymNames.tell ());
564
- SymNames << Name << ' \0 ' ;
619
+ (*Map)[Name] = Index;
620
+ if (Map == &SymMap->Map ) {
621
+ Ret.push_back (SymNames.tell ());
622
+ SymNames << Name << ' \0 ' ;
623
+ }
565
624
} else {
566
625
Ret.push_back (SymNames.tell ());
567
626
if (Error E = S.printName (SymNames))
@@ -755,7 +814,7 @@ Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To) {
755
814
static Error writeArchiveToStream (raw_ostream &Out,
756
815
ArrayRef<NewArchiveMember> NewMembers,
757
816
bool WriteSymtab, object::Archive::Kind Kind,
758
- bool Deterministic, bool Thin) {
817
+ bool Deterministic, bool Thin, bool IsEC ) {
759
818
assert ((!Thin || !isBSDLike (Kind)) && " Only the gnu format has a thin mode" );
760
819
761
820
SmallString<0 > SymNamesBuf;
@@ -769,6 +828,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
769
828
if (isCOFFArchive (Kind) && NewMembers.size () > 0xfffe )
770
829
Kind = object::Archive::K_GNU;
771
830
831
+ SymMap.UseECMap = IsEC;
772
832
Expected<std::vector<MemberData>> DataOrErr = computeMemberData (
773
833
StringTable, SymNames, Kind, Thin, Deterministic, WriteSymtab,
774
834
isCOFFArchive (Kind) ? &SymMap : nullptr , NewMembers);
@@ -855,6 +915,9 @@ static Error writeArchiveToStream(raw_ostream &Out,
855
915
Out << StringTableMember.Header << StringTableMember.Data
856
916
<< StringTableMember.Padding ;
857
917
918
+ if (WriteSymtab && SymMap.ECMap .size ())
919
+ writeECSymbols (Out, Kind, Deterministic, Data, SymMap);
920
+
858
921
for (const MemberData &M : Data)
859
922
Out << M.Header << M.Data << M.Padding ;
860
923
} else {
@@ -944,15 +1007,15 @@ static Error writeArchiveToStream(raw_ostream &Out,
944
1007
Error writeArchive (StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
945
1008
bool WriteSymtab, object::Archive::Kind Kind,
946
1009
bool Deterministic, bool Thin,
947
- std::unique_ptr<MemoryBuffer> OldArchiveBuf) {
1010
+ std::unique_ptr<MemoryBuffer> OldArchiveBuf, bool IsEC ) {
948
1011
Expected<sys::fs::TempFile> Temp =
949
1012
sys::fs::TempFile::create (ArcName + " .temp-archive-%%%%%%%.a" );
950
1013
if (!Temp)
951
1014
return Temp.takeError ();
952
1015
raw_fd_ostream Out (Temp->FD , false );
953
1016
954
1017
if (Error E = writeArchiveToStream (Out, NewMembers, WriteSymtab, Kind,
955
- Deterministic, Thin)) {
1018
+ Deterministic, Thin, IsEC )) {
956
1019
if (Error DiscardError = Temp->discard ())
957
1020
return joinErrors (std::move (E), std::move (DiscardError));
958
1021
return E;
@@ -981,7 +1044,7 @@ writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers, bool WriteSymtab,
981
1044
raw_svector_ostream ArchiveStream (ArchiveBufferVector);
982
1045
983
1046
if (Error E = writeArchiveToStream (ArchiveStream, NewMembers, WriteSymtab,
984
- Kind, Deterministic, Thin))
1047
+ Kind, Deterministic, Thin, false ))
985
1048
return std::move (E);
986
1049
987
1050
return std::make_unique<SmallVectorMemoryBuffer>(
0 commit comments