LLVM: lib/Object/ArchiveWriter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
37
38#include
39#include
40
41#if !defined(_MSC_VER) && !defined(__MINGW32__)
42#include <unistd.h>
43#else
44#include <io.h>
45#endif
46
47using namespace llvm;
49
52 std::map<std::string, uint16_t> Map;
53 std::map<std::string, uint16_t> ECMap;
54};
55
58 MemberName(BufRef.getBufferIdentifier()) {}
59
61 auto MemBufferRef = this->Buf->getMemBufferRef();
64
65 if (OptionalObject) {
66 if (isaobject::MachOObjectFile(**OptionalObject))
68 if (isaobject::XCOFFObjectFile(**OptionalObject))
70 if (isaobject::COFFObjectFile(**OptionalObject) ||
71 isaobject::COFFImportFile(**OptionalObject))
74 }
75
76
78
79
80
85 auto &IRObject = castobject::IRObjectFile(**ObjOrErr);
86 auto TargetTriple = Triple(IRObject.getTargetTriple());
88 } else {
89
91 }
92 }
93
95}
96
99 bool Deterministic) {
101 if (!BufOrErr)
103
106 M.MemberName = M.Buf->getBufferIdentifier();
107 if (!Deterministic) {
109 if (!ModTimeOrErr)
110 return ModTimeOrErr.takeError();
111 M.ModTime = ModTimeOrErr.get();
113 if (!UIDOrErr)
115 M.UID = UIDOrErr.get();
117 if (!GIDOrErr)
119 M.GID = GIDOrErr.get();
121 if (!AccessModeOrErr)
122 return AccessModeOrErr.takeError();
123 M.Perms = AccessModeOrErr.get();
124 }
125 return std::move(M);
126}
127
129 bool Deterministic) {
132 if (!FDOrErr)
133 return FDOrErr.takeError();
136
139
140
141
142
145
148 if (!MemberBufferOrErr)
150
153
155 M.Buf = std::move(*MemberBufferOrErr);
156 M.MemberName = M.Buf->getBufferIdentifier();
157 if (!Deterministic) {
158 M.ModTime = std::chrono::time_point_caststd::chrono::seconds(
159 Status.getLastModificationTime());
160 M.UID = Status.getUser();
161 M.GID = Status.getGroup();
162 M.Perms = Status.permissions();
163 }
164 return std::move(M);
165}
166
167template
171 unsigned SizeSoFar = OS.tell() - OldPos;
172 assert(SizeSoFar <= Size && "Data doesn't fit in Size");
174}
175
179}
180
183}
184
187}
188
190 switch (Kind) {
195 return false;
199 return true;
200 }
202}
203
204template
209}
210
213}
214
217 unsigned UID, unsigned GID, unsigned Perms, uint64_t Size) {
219
220
221
224
227 Out << "`\n";
228}
229
230static void
233 unsigned UID, unsigned GID, unsigned Perms,
237}
238
239static void
242 unsigned UID, unsigned GID, unsigned Perms, uint64_t Size) {
243 uint64_t PosAfterHeader = Pos + 60 + Name.size();
244
246 unsigned NameWithPadding = Name.size() + Pad;
249 NameWithPadding + Size);
251 while (Pad--)
253}
254
255static void
258 unsigned UID, unsigned GID, unsigned Perms,
261 unsigned NameLen = Name.size();
262
267
272 if (NameLen) {
274 if (NameLen % 2)
276 }
277 Out << "`\n";
278}
279
281 return Thin || Name.size() >= 16 || Name.contains('/');
282}
283
285 switch (Kind) {
290 return false;
294 return true;
295 }
297}
298
299static void
306 M.Perms, Size);
309 M.Perms, Size);
310 Out << '/';
312 if (Thin) {
315 } else {
316 auto Insertion = MemberNames.insert({M.MemberName, uint64_t(0)});
317 if (Insertion.second) {
318 Insertion.first->second = StringTable.tell();
322 else
324 }
325 NamePos = Insertion.first->second;
326 }
329}
330
331namespace {
332struct MemberData {
333 std::vector Symbols;
334 std::string Header;
338 std::unique_ptr SymFile = nullptr;
339};
340}
341
343 unsigned Size = Names.size();
345 std::string Header;
349 Out << "`\n";
351 return {{}, std::move(Header), Names, Pad ? "\n" : ""};
352}
353
355 using namespace std::chrono;
356
357 if (!Deterministic)
358 return time_point_cast(system_clock::now());
360}
361
364 if (!SymFlagsOrErr)
365
368 return false;
370 return false;
372 return false;
373 return true;
374}
375
379 print<uint64_t>(Out, Kind, Val);
380 else
381 print<uint32_t>(Out, Kind, Val);
382}
383
387 uint32_t *Padding = nullptr) {
388 assert((OffsetSize == 4 || OffsetSize == 8) && "Unsupported OffsetSize");
389 uint64_t Size = OffsetSize;
391 Size += NumSyms * OffsetSize * 2;
392 else
393 Size += NumSyms * OffsetSize;
395 Size += OffsetSize;
396 Size += StringTableSize;
397
398
399
400
401
402
404 ? 0
406
408 if (Padding)
409 *Padding = Pad;
411}
412
414 uint32_t *Padding = nullptr) {
415 uint64_t Size = sizeof(uint32_t) * 2;
416 Size += NumObj * sizeof(uint32_t);
417
419 Size += sizeof(uint16_t) + S.first.length() + 1;
420
423 if (Padding)
424 *Padding = Pad;
426}
427
429 uint32_t *Padding = nullptr) {
431
433 Size += sizeof(uint16_t) + S.first.length() + 1;
434
437 if (Padding)
438 *Padding = Pad;
440}
441
444 uint64_t PrevMemberOffset = 0,
445 uint64_t NextMemberOffset = 0) {
452 PrevMemberOffset, NextMemberOffset);
453 } else {
456 }
457}
458
466 auto computeSymbolTableHeaderSize = [=] {
470 return TmpBuf.size();
471 };
472 uint32_t HeaderSize = computeSymbolTableHeaderSize();
473 uint64_t Size = strlen("!\n") + HeaderSize + SymtabSize;
474
479 }
480
481 return Size + StringMemberSize;
482}
483
488
490 return nullptr;
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510 if (!ObjOrErr) {
511 switch (Kind) {
515 Warn(ObjOrErr.takeError());
516 return nullptr;
521 return ObjOrErr.takeError();
522 }
523 }
524 return std::move(*ObjOrErr);
525 } else {
527 if (!ObjOrErr)
528 return ObjOrErr.takeError();
529 return std::move(*ObjOrErr);
530 }
531}
532
534 return SymObj != nullptr ? SymObj->is64Bit() : false;
535}
536
537
539
540
541
542
543
545
546template
549
550
551 if (AuxHeader == nullptr)
553
554
555
556
557
558 if (AuxHeaderSize < offsetof(AuxiliaryHeader, ModuleType))
560
561
562
563 if (AuxHeader->SecNumOfLoader == 0)
565
566
567
568
569
570
572 std::max(AuxHeader->MaxAlignOfText, AuxHeader->MaxAlignOfData);
573 return 1 << (Log2OfAlign > Log2OfAIXPageSize ? Log2OfMaxAlign : Log2OfAlign);
574}
575
576
577
578
579
581 XCOFFObjectFile *XCOFFObj = dyn_cast_or_null(SymObj);
582 if (!XCOFFObj)
584
585
586
587 return XCOFFObj->is64Bit()
593}
594
598 unsigned NumSyms, uint64_t PrevMemberOffset = 0,
599 uint64_t NextMemberOffset = 0,
600 bool Is64Bit = false) {
601
602
604 return;
605
611 NextMemberOffset);
612
615 else
617
618 uint64_t Pos = MembersOffset;
619 for (const MemberData &M : Members) {
621 Pos += M.PreHeadPadSize;
623 Pos += M.Header.size() + M.Data.size() + M.Padding.size();
624 continue;
625 }
626 }
627
628 for (unsigned StringOffset : M.Symbols) {
632 }
633 Pos += M.Header.size() + M.Data.size() + M.Padding.size();
634 }
635
637
640
641 while (Pad--)
643}
644
651
652 uint32_t Pos = MembersOffset;
653
654 printLE<uint32_t>(Out, Members.size());
655 for (const MemberData &M : Members) {
656 printLE(Out, Pos);
657 Pos += M.Header.size() + M.Data.size() + M.Padding.size();
658 }
659
660 printLE<uint32_t>(Out, SymMap.Map.size());
661
665 Out << S.first << '\0';
666
667 while (Pad--)
669}
670
678
679 printLE<uint32_t>(Out, SymMap.ECMap.size());
680
684 Out << S.first << '\0';
685 while (Pad--)
687}
688
691 return castllvm::object::COFFObjectFile(&Obj)->getMachine() !=
693
695 return castllvm::object::COFFImportFile(&Obj)->getMachine() !=
697
698 if (Obj.isIR()) {
701 if (!TripleStr)
702 return false;
704 return T.isWindowsArm64EC() || T.getArch() == Triple::x86_64;
705 }
706
707 return false;
708}
709
712 return COFF::isAnyArm64(cast(&Obj)->getMachine());
713
715 return COFF::isAnyArm64(cast(&Obj)->getMachine());
716
717 if (Obj.isIR()) {
720 if (!TripleStr)
721 return false;
724 }
725
726 return false;
727}
728
734}
735
740 std::vector Ret;
741
742 if (Obj == nullptr)
743 return Ret;
744
745 std::map<std::string, uint16_t> *Map = nullptr;
748
751 continue;
752 if (Map) {
753 std::string Name;
755 if (Error E = S.printName(NameStream))
756 return std::move(E);
757 if (!Map->try_emplace(Name, Index).second)
758 continue;
760 Ret.push_back(SymNames.tell());
761 SymNames << Name << '\0';
762
763
766 }
767 } else {
768 Ret.push_back(SymNames.tell());
769 if (Error E = S.printName(SymNames))
770 return std::move(E);
771 SymNames << '\0';
772 }
773 }
774 return Ret;
775}
776
783 static char PaddingData[8] = {'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'};
787
788 std::vector Ret;
789 bool HasObject = false;
790
791
792
793
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837 bool UniqueTimestamps = Deterministic && isDarwin(Kind);
838 std::map<StringRef, unsigned> FilenameCount;
839 if (UniqueTimestamps) {
841 FilenameCount[M.MemberName]++;
842 for (auto &Entry : FilenameCount)
843 Entry.second = Entry.second > 1 ? 1 : 0;
844 }
845
846 std::vector<std::unique_ptr> SymFiles;
847
851 M.Buf->getMemBufferRef(), Context, Kind, [&](Error Err) {
852 Warn(createFileError(M.MemberName, std::move(Err)));
853 });
854 if (!SymFileOrErr)
856 SymFiles.push_back(std::move(*SymFileOrErr));
857 }
858 }
859
861 if (IsEC) {
863 } else {
864
865
866
867
868 bool HaveArm64 = false, HaveEC = false;
869 for (std::unique_ptr &SymFile : SymFiles) {
870 if (!SymFile)
871 continue;
872 if (!HaveArm64)
874 if (!HaveEC)
876 if (HaveArm64 && HaveEC) {
878 break;
879 }
880 }
881 }
882 }
883
884
885
887 uint64_t NextMemHeadPadSize = 0;
888
889 for (uint32_t Index = 0; Index < NewMembers.size(); ++Index) {
891 std::string Header;
893
896
897
898
899
900
901 unsigned MemberPadding =
903 unsigned TailPadding =
905 StringRef Padding = StringRef(PaddingData, MemberPadding + TailPadding);
906
908 if (UniqueTimestamps)
909
911 else
912 ModTime = M->ModTime;
913
916 std::string StringMsg =
917 "File " + M->MemberName.str() + " exceeds size limit";
918 return make_errorobject::GenericBinaryError(
920 }
921
922 std::unique_ptr CurSymFile;
923 if (!SymFiles.empty())
924 CurSymFile = std::move(SymFiles[Index]);
925
926
927
930 alignTo(M->MemberName.size(), 2);
931
932 if (M == NewMembers.begin())
933 NextMemHeadPadSize =
936 OffsetToMemData;
937
938 MemHeadPadSize = NextMemHeadPadSize;
939 Pos += MemHeadPadSize;
942
943
944
945 if (Index + 1 != SymFiles.size()) {
946 uint64_t OffsetToNextMemData =
948 alignTo(NewMembers[Index + 1].MemberName.size(), 2);
949 NextMemHeadPadSize =
952 OffsetToNextMemData;
953 NextOffset += NextMemHeadPadSize;
954 }
956 M->Perms, Size, PrevOffset, NextOffset);
957 PrevOffset = Pos;
958 } else {
960 ModTime, Size);
961 }
963
964 std::vector Symbols;
968 if (!SymbolsOrErr)
970 Symbols = std::move(*SymbolsOrErr);
971 if (CurSymFile)
972 HasObject = true;
973 }
974
975 Pos += Header.size() + Data.size() + Padding.size();
976 Ret.push_back({std::move(Symbols), std::move(Header), Data, Padding,
977 MemHeadPadSize, std::move(CurSymFile)});
978 }
979
980
981
983 SymNames << '\0' << '\0' << '\0';
984 return std::move(Ret);
985}
986
987namespace llvm {
988
992 if (Err)
993 return Err;
995 return Ret;
996}
997
998
1002 if (!PathToOrErr || !DirFromOrErr)
1004
1007
1008
1011
1012
1013 auto FromTo =
1016 auto FromI = FromTo.first;
1017 auto ToI = FromTo.second;
1018
1019
1021 for (auto FromE = sys::path::end(DirFrom); FromI != FromE; ++FromI)
1023
1024 for (auto ToE = sys::path::end(PathTo); ToI != ToE; ++ToI)
1026
1027 return std::string(Relative);
1028}
1029
1034 bool Thin, std::optional IsEC,
1036 assert((!Thin || (Kind)) && "Only the gnu format has a thin mode");
1037
1044
1045
1046
1047
1050
1051
1052
1054
1056 StringTable, SymNames, Kind, Thin, Deterministic, WriteSymtab,
1059 return E;
1060 std::vector &Data = *DataOrErr;
1061
1062 uint64_t StringTableSize = 0;
1063 MemberData StringTableMember;
1066 StringTableSize = StringTableMember.Header.size() +
1067 StringTableMember.Data.size() +
1068 StringTableMember.Padding.size();
1069 }
1070
1071
1072 uint64_t LastMemberEndOffset = 0;
1073 uint64_t LastMemberHeaderOffset = 0;
1075 uint64_t NumSyms32 = 0;
1076
1077 for (const auto &M : Data) {
1078
1079 LastMemberEndOffset += M.PreHeadPadSize;
1080 LastMemberHeaderOffset = LastMemberEndOffset;
1081
1082 LastMemberEndOffset += M.Header.size() + M.Data.size() + M.Padding.size();
1083 NumSyms += M.Symbols.size();
1084
1085
1086
1087
1088
1089
1092 NumSyms32 += M.Symbols.size();
1093 }
1094 }
1095
1096 std::optional<uint64_t> HeadersSize;
1097
1098
1099
1101
1103 NumSyms, SymNamesBuf.size(),
1105
1106
1107
1108
1109
1110
1111
1112
1113 uint64_t Sym64Threshold = 1ULL << 32;
1114 const char *Sym64Env = std::getenv("SYM64_THRESHOLD");
1115 if (Sym64Env)
1117
1118
1119
1120
1121 if (*HeadersSize + LastMemberHeaderOffset >= Sym64Threshold) {
1124 else
1126 HeadersSize.reset();
1127 }
1128 }
1129
1130 if (Thin)
1131 Out << "!\n";
1133 Out << "\n";
1134 else
1135 Out << "!\n";
1136
1138 if (ShouldWriteSymtab) {
1139 if (!HeadersSize)
1141 Kind, Data.size(), StringTableSize, NumSyms, SymNamesBuf.size(),
1144 *HeadersSize, NumSyms);
1145
1148 }
1149
1150 if (StringTableSize)
1151 Out << StringTableMember.Header << StringTableMember.Data
1152 << StringTableMember.Padding;
1153
1154 if (ShouldWriteSymtab && SymMap.ECMap.size())
1156
1157 for (const MemberData &M : Data)
1158 Out << M.Header << M.Data << M.Padding;
1159 } else {
1161 LastMemberEndOffset += *HeadersSize;
1162 LastMemberHeaderOffset += *HeadersSize;
1163
1164
1165
1166 uint64_t MemberTableNameStrTblSize = 0;
1167 std::vector<size_t> MemberOffsets;
1168 std::vector MemberNames;
1169
1171 for (size_t I = 0, Size = NewMembers.size(); I != Size; ++I) {
1173 MemberTableNameStrTblSize += Member.MemberName.size() + 1;
1174 MemberEndOffset += Data[I].PreHeadPadSize;
1175 MemberOffsets.push_back(MemberEndOffset);
1176 MemberNames.push_back(Member.MemberName);
1177
1178
1181 alignTo(Member.MemberName.size(), 2);
1182 }
1183
1184
1185 uint64_t MemberTableSize = 20 +
1186 20 * MemberOffsets.size() +
1187 MemberTableNameStrTblSize;
1188
1193
1194 if (ShouldWriteSymtab && NumSyms)
1195
1196 for (const auto &M : Data) {
1198 M.SymFile.get(), 0,
1200 nullptr);
1201 if (!SymbolsOrErr)
1202 return SymbolsOrErr.takeError();
1203 }
1204
1205 uint64_t MemberTableEndOffset =
1206 LastMemberEndOffset +
1208
1209
1210
1211
1212 uint64_t GlobalSymbolOffset =
1213 (ShouldWriteSymtab &&
1215 ? MemberTableEndOffset
1216 : 0;
1217
1218 uint64_t GlobalSymbolOffset64 = 0;
1219 uint64_t NumSyms64 = NumSyms - NumSyms32;
1221 NumSyms64 > 0) {
1222 if (GlobalSymbolOffset == 0)
1223 GlobalSymbolOffset64 = MemberTableEndOffset;
1224 else
1225
1226
1227 GlobalSymbolOffset64 =
1229 (NumSyms32 + 1) * 8 + alignTo(SymNamesBuf32.size(), 2);
1230 }
1231
1232
1234 20);
1235
1236
1240 NewMembers.size()
1242 Data[0].PreHeadPadSize
1243 : 0,
1244 20);
1246 20);
1248 Out, 0,
1249 20);
1250
1251 for (const MemberData &M : Data) {
1252 Out << std::string(M.PreHeadPadSize, '\0');
1253 Out << M.Header << M.Data;
1254 if (M.Data.size() % 2)
1255 Out << '\0';
1256 }
1257
1258 if (NewMembers.size()) {
1259
1261 MemberTableSize, LastMemberHeaderOffset,
1262 GlobalSymbolOffset ? GlobalSymbolOffset
1263 : GlobalSymbolOffset64);
1265 for (uint64_t MemberOffset : MemberOffsets)
1267 20);
1268 for (StringRef MemberName : MemberNames)
1269 Out << MemberName << '\0';
1270
1271 if (MemberTableNameStrTblSize % 2)
1272 Out << '\0';
1273
1274
1275 if (ShouldWriteSymtab) {
1276
1277 if (GlobalSymbolOffset) {
1279 *HeadersSize, NumSyms32, LastMemberEndOffset,
1280 GlobalSymbolOffset64);
1281
1282 if (GlobalSymbolOffset64 && (SymNamesBuf32.size() % 2))
1283 Out << '\0';
1284 }
1285
1286
1287 if (GlobalSymbolOffset64)
1289 *HeadersSize, NumSyms64,
1290 GlobalSymbolOffset ? GlobalSymbolOffset
1291 : LastMemberEndOffset,
1292 0, true);
1293 }
1294 }
1295 }
1298}
1299
1302}
1303
1306 bool Deterministic, bool Thin,
1307 std::unique_ptr OldArchiveBuf,
1311 if (!Temp)
1314
1316 Deterministic, Thin, IsEC, Warn)) {
1317 if (Error DiscardError = Temp->discard())
1318 return joinErrors(std::move(E), std::move(DiscardError));
1319 return E;
1320 }
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332 OldArchiveBuf.reset();
1333
1334 return Temp->keep(ArcName);
1335}
1336
1340 bool Deterministic, bool Thin,
1344
1347 Deterministic, Thin, std::nullopt, Warn))
1348 return std::move(E);
1349
1350 return std::make_unique(
1351 std::move(ArchiveBufferVector), false);
1352}
1353
1354}
This file defines the StringMap class.
#define offsetof(TYPE, MEMBER)
static void printNBits(raw_ostream &Out, object::Archive::Kind Kind, uint64_t Val)
bool isImportDescriptor(StringRef Name)
static sys::TimePoint< std::chrono::seconds > now(bool Deterministic)
static bool isDarwin(object::Archive::Kind Kind)
static uint64_t computeECSymbolsSize(SymMap &SymMap, uint32_t *Padding=nullptr)
static Expected< std::vector< unsigned > > getSymbols(SymbolicFile *Obj, uint16_t Index, raw_ostream &SymNames, SymMap *SymMap)
static bool is64BitSymbolicFile(const SymbolicFile *SymObj)
static uint64_t computeHeadersSize(object::Archive::Kind Kind, uint64_t NumMembers, uint64_t StringMemberSize, uint64_t NumSyms, uint64_t SymNamesSize, SymMap *SymMap)
static bool isBSDLike(object::Archive::Kind Kind)
static void printBSDMemberHeader(raw_ostream &Out, uint64_t Pos, StringRef Name, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, uint64_t Size)
static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind, bool Deterministic, ArrayRef< MemberData > Members, StringRef StringTable, uint64_t MembersOffset, unsigned NumSyms, uint64_t PrevMemberOffset=0, uint64_t NextMemberOffset=0, bool Is64Bit=false)
static const uint32_t MinBigArchiveMemDataAlign
static void writeSymbolMap(raw_ostream &Out, object::Archive::Kind Kind, bool Deterministic, ArrayRef< MemberData > Members, SymMap &SymMap, uint64_t MembersOffset)
static MemberData computeStringTable(StringRef Names)
uint16_t getAuxMaxAlignment(uint16_t AuxHeaderSize, AuxiliaryHeader *AuxHeader, uint16_t Log2OfMaxAlign)
static const uint32_t Log2OfAIXPageSize
static bool isECObject(object::SymbolicFile &Obj)
static Expected< std::unique_ptr< SymbolicFile > > getSymbolicFile(MemoryBufferRef Buf, LLVMContext &Context, object::Archive::Kind Kind, function_ref< void(Error)> Warn)
static bool isAIXBigArchive(object::Archive::Kind Kind)
static void writeSymbolTableHeader(raw_ostream &Out, object::Archive::Kind Kind, bool Deterministic, uint64_t Size, uint64_t PrevMemberOffset=0, uint64_t NextMemberOffset=0)
static void printRestOfMemberHeader(raw_ostream &Out, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, uint64_t Size)
static uint64_t computeSymbolTableSize(object::Archive::Kind Kind, uint64_t NumSyms, uint64_t OffsetSize, uint64_t StringTableSize, uint32_t *Padding=nullptr)
static bool isArchiveSymbol(const object::BasicSymbolRef &S)
static bool isCOFFArchive(object::Archive::Kind Kind)
static Expected< std::vector< MemberData > > computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames, object::Archive::Kind Kind, bool Thin, bool Deterministic, SymtabWritingMode NeedSymbols, SymMap *SymMap, LLVMContext &Context, ArrayRef< NewArchiveMember > NewMembers, std::optional< bool > IsEC, function_ref< void(Error)> Warn)
static void printMemberHeader(raw_ostream &Out, uint64_t Pos, raw_ostream &StringTable, StringMap< uint64_t > &MemberNames, object::Archive::Kind Kind, bool Thin, const NewArchiveMember &M, sys::TimePoint< std::chrono::seconds > ModTime, uint64_t Size)
static void writeECSymbols(raw_ostream &Out, object::Archive::Kind Kind, bool Deterministic, ArrayRef< MemberData > Members, SymMap &SymMap)
static uint64_t computeSymbolMapSize(uint64_t NumObj, SymMap &SymMap, uint32_t *Padding=nullptr)
static void printLE(raw_ostream &Out, T Val)
static void printGNUSmallMemberHeader(raw_ostream &Out, StringRef Name, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, uint64_t Size)
static bool useStringTable(bool Thin, StringRef Name)
static bool is64BitKind(object::Archive::Kind Kind)
static uint32_t getMemberAlignment(SymbolicFile *SymObj)
static void printBigArchiveMemberHeader(raw_ostream &Out, StringRef Name, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, uint64_t Size, uint64_t PrevOffset, uint64_t NextOffset)
static void printWithSpacePadding(raw_ostream &OS, T Data, unsigned Size)
static bool isAnyArm64COFF(object::SymbolicFile &Obj)
BlockVerifier::State From
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Represents either an error or a value T.
std::error_code getError() const
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
This is an important class for using LLVM in a threaded context.
size_t getBufferSize() const
StringRef getBuffer() const
This interface provides simple read-only access to a block of memory, and provides simple methods for...
static ErrorOr< std::unique_ptr< MemoryBuffer > > getOpenFile(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Given an already-open file descriptor, read the file and return a MemoryBuffer.
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr size_t size() const
size - Get the string size.
A table of densely packed, null-terminated strings indexed by offset.
constexpr size_t size() const
Returns the byte size of the table.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
An efficient, type-erasing, non-owning reference to a callable.
Expected< unsigned > getGID() const
Expected< MemoryBufferRef > getMemoryBufferRef() const
Expected< unsigned > getUID() const
Expected< sys::fs::perms > getAccessMode() const
Expected< sys::TimePoint< std::chrono::seconds > > getLastModified() const
static object::Archive::Kind getDefaultKind()
static object::Archive::Kind getDefaultKindForTriple(const Triple &T)
static const uint64_t MaxMemberSize
Size field is 10 decimal digits long.
This is a value type class that represents a single symbol in the list of symbols in the object file.
Expected< uint32_t > getFlags() const
Get symbol flags (bitwise OR of SymbolRef::Flags)
bool isCOFFImportFile() const
MemoryBufferRef getMemoryBufferRef() const
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
static Expected< std::unique_ptr< SymbolicFile > > createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type, LLVMContext *Context, bool InitContent=true)
virtual bool is64Bit() const =0
basic_symbol_iterator_range symbols() const
static bool isSymbolicFile(file_magic Type, const LLVMContext *Context)
const XCOFFAuxiliaryHeader32 * auxiliaryHeader32() const
const XCOFFFileHeader64 * fileHeader64() const
const XCOFFFileHeader32 * fileHeader32() const
const XCOFFAuxiliaryHeader64 * auxiliaryHeader64() const
bool is64Bit() const override
A raw_ostream that writes to a file descriptor.
This class implements an extremely fast bulk output stream that can only output to a stream.
uint64_t tell() const
tell - Return the current offset with the file.
raw_ostream & write(unsigned char C)
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
static Expected< TempFile > create(const Twine &Model, unsigned Mode=all_read|all_write, OpenFlags ExtraFlags=OF_None)
This creates a temporary file with createUniqueFile and schedules it for deletion with sys::RemoveFil...
Represents the result of a call to sys::fs::status().
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ IMAGE_FILE_MACHINE_ARM64
bool isAnyArm64(T Machine)
constexpr std::string_view NullImportDescriptorSymbolName
constexpr std::string_view NullThunkDataPrefix
constexpr std::string_view NullThunkDataSuffix
constexpr std::string_view ImportDescriptorPrefix
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
void make_absolute(const Twine ¤t_directory, SmallVectorImpl< char > &path)
Make path an absolute path.
const file_t kInvalidFile
std::error_code closeFile(file_t &F)
Close the file object.
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
Expected< file_t > openNativeFileForRead(const Twine &Name, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)
Opens the file with the given name in a read-only mode, returning its open file descriptor.
const_iterator begin(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get begin iterator over path.
bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
std::string convert_to_slash(StringRef path, Style style=Style::native)
Replaces backslashes with slashes if Windows.
StringRef root_name(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get root name.
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
const_iterator end(StringRef path LLVM_LIFETIME_BOUND)
Get end iterator over path.
std::chrono::time_point< std::chrono::system_clock, D > TimePoint
A time point on the system clock.
TimePoint< std::chrono::seconds > toTimePoint(std::time_t T)
Convert a std::time_t to a TimePoint.
std::time_t toTimeT(TimePoint<> TP)
Convert a TimePoint to std::time_t.
This is an optimization pass for GlobalISel generic memory operations.
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Expected< std::unique_ptr< MemoryBuffer > > writeArchiveToBuffer(ArrayRef< NewArchiveMember > NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, function_ref< void(Error)> Warn=warnToStderr)
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Error writeArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr, std::optional< bool > IsEC=std::nullopt, function_ref< void(Error)> Warn=warnToStderr)
std::error_code make_error_code(BitcodeError E)
Expected< std::string > getBitcodeTargetTriple(MemoryBufferRef Buffer)
Read the header of the specified bitcode buffer and extract just the triple information.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)
Error joinErrors(Error E1, Error E2)
Concatenate errors.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
constexpr T alignToPowerOf2(U Value, V Align)
Will overflow only if result is not representable in T.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void warnToStderr(Error Err)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Expected< std::string > computeArchiveRelativePath(StringRef From, StringRef To)
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
static ErrorOr< SmallString< 128 > > canonicalizePath(StringRef P)
std::error_code errnoAsErrorCode()
Helper to get errno as an std::error_code.
Error writeArchiveToStream(raw_ostream &Out, ArrayRef< NewArchiveMember > NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::optional< bool > IsEC=std::nullopt, function_ref< void(Error)> Warn=warnToStderr)
void consumeError(Error Err)
Consume a Error without doing anything.
std::map< std::string, uint16_t > ECMap
std::map< std::string, uint16_t > Map
This struct is a compact representation of a valid (non-zero power of two) alignment.
object::Archive::Kind detectKindFromObject() const
NewArchiveMember()=default
static Expected< NewArchiveMember > getFile(StringRef FileName, bool Deterministic)
static Expected< NewArchiveMember > getOldMember(const object::Archive::Child &OldMember, bool Deterministic)
std::unique_ptr< MemoryBuffer > Buf
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...