LLVM: lib/Object/XCOFFObjectFile.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
18#include
19#include
20
21namespace llvm {
22
23using namespace XCOFF;
24
25namespace object {
26
30
31
32
33template
36 uintptr_t Addr = reinterpret_cast<uintptr_t>(Ptr);
38 return std::move(E);
39 return reinterpret_cast<const T *>(Addr);
40}
41
43 return reinterpret_cast<uintptr_t>(reinterpret_cast<const char *>(Base) +
45}
46
47template static const T *viewAs(uintptr_t in) {
48 return reinterpret_cast<const T *>(in);
49}
50
52 auto NulCharPtr =
56}
57
59 const T &DerivedXCOFFSectionHeader = static_cast<const T &>(*this);
61}
62
64 const T &DerivedXCOFFSectionHeader = static_cast<const T &>(*this);
65 return DerivedXCOFFSectionHeader.Flags & SectionFlagsTypeMask;
66}
67
68template
70 const T &DerivedXCOFFSectionHeader = static_cast<const T &>(*this);
71 return DerivedXCOFFSectionHeader.Flags & ~SectionFlagsTypeMask;
72}
73
74template
76 return getSectionType() & SectionFlagsReservedMask;
77}
78
79template
82}
83
84template
87}
88
89template
91
92
94}
95
98
99template
102 if (LoaderSecHeader->LengthOfStrTbl > Offset)
103 return (reinterpret_cast<const char *>(LoaderSecHeader) +
104 LoaderSecHeader->OffsetToStrTbl + Offset);
105
107 " in the loader section's string table with size 0x" +
109 " is invalid");
110}
111
118
120}
121
125}
126
127uintptr_t
131}
132
135 assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
136 return viewAsXCOFF::SymbolAuxType(
138}
139
140void XCOFFObjectFile::checkSectionAddress(uintptr_t Addr,
141 uintptr_t TableAddress) const {
142 if (Addr < TableAddress)
143 report_fatal_error("Section header outside of section header table.");
144
145 uintptr_t Offset = Addr - TableAddress;
147 report_fatal_error("Section header outside of section header table.");
148
149 if (Offset % getSectionHeaderSize() != 0)
151 "Section header pointer does not point to a valid section header.");
152}
153
154const XCOFFSectionHeader32 *
155XCOFFObjectFile::toSection32(DataRefImpl Ref) const {
156 assert(() && "32-bit interface called on 64-bit object file.");
157#ifndef NDEBUG
158 checkSectionAddress(Ref.p, getSectionHeaderTableAddress());
159#endif
160 return viewAs(Ref.p);
161}
162
163const XCOFFSectionHeader64 *
164XCOFFObjectFile::toSection64(DataRefImpl Ref) const {
165 assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
166#ifndef NDEBUG
167 checkSectionAddress(Ref.p, getSectionHeaderTableAddress());
168#endif
169 return viewAs(Ref.p);
173 assert(Ref.p != 0 && "Symbol table pointer can not be nullptr!");
174#ifndef NDEBUG
176#endif
178}
179
181 assert(() && "32-bit interface called on 64-bit object file.");
183}
184
186 assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
188}
189
191 assert(() && "32-bit interface called on 64-bit object file.");
193}
194
196 assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
198}
199
200template const T *XCOFFObjectFile::sectionHeaderTable() const {
201 return static_cast<const T *>(SectionHeaderTable);
202}
203
204const XCOFFSectionHeader32 *
205XCOFFObjectFile::sectionHeaderTable32() const {
206 assert(() && "32-bit interface called on 64-bit object file.");
207 return static_cast<const XCOFFSectionHeader32 *>(SectionHeaderTable);
208}
209
210const XCOFFSectionHeader64 *
211XCOFFObjectFile::sectionHeaderTable64() const {
212 assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
213 return static_cast<const XCOFFSectionHeader64 *>(SectionHeaderTable);
214}
215
218 Symb.p, toSymbolRef(Symb).getNumberOfAuxEntries() + 1);
219#ifndef NDEBUG
220
221
222 if (NextSymbolAddr != getEndOfSymbolTableAddress())
224#endif
225 Symb.p = NextSymbolAddr;
226}
227
230
231
232
233
234
237
240
242 " in a string table with size 0x" +
244}
245
247
248
251}
252
258}
259
262}
263
266}
267
270}
271
278 if (!CsectAuxRefOrError)
279
281 else
282 Result = 1ULL << CsectAuxRefOrError.get().getAlignmentLog2();
283 }
284 return Result;
285}
286
293 if (!CsectAuxRefOrError)
294
296 else {
300 }
301 }
302 return Result;
303}
304
308
310 if (!IsFunction)
311 return IsFunction.takeError();
312
313 if (*IsFunction)
315
318
320 if (SecNum <= 0)
322
325
326 if (!SecDRIOrErr)
328
330
332 if (SymNameOrError) {
333
334 if (SymNameOrError.get() == "TOC")
336
337
340 SecName = XCOFFObjectFile::toSection64(SecDRIOrErr.get())->getName();
341 else
342 SecName = XCOFFObjectFile::toSection32(SecDRIOrErr.get())->getName();
343
344 if (SecName == SymNameOrError.get())
346 } else
347 return SymNameOrError.takeError();
348
351
354
356}
357
361
362 if (isReservedSectionNumber(SectNum))
364
366 if (!ExpSec)
368
370}
371
373 const char *Ptr = reinterpret_cast<const char *>(Sec.p);
374 Sec.p = reinterpret_cast<uintptr_t>(Ptr + getSectionHeaderSize());
375}
376
379}
380
382
383
386
388}
389
391
392
394 return toSection64(Sec) - sectionHeaderTable64() + 1;
395 else
396 return toSection32(Sec) - sectionHeaderTable32() + 1;
397}
398
400
401
404
406}
407
412
416 else
418
419 const uint8_t * ContentStart = base() + OffsetToRaw;
422 Data, reinterpret_cast<uintptr_t>(ContentStart), SectionSize))
424 toString(std::move(E)) + ": section data with offset 0x" +
426 Twine::utohexstr(SectionSize) + " goes past the end of the file");
427
428 return ArrayRef(ContentStart, SectionSize);
429}
430
434 return Result;
435}
436
437uint64_t XCOFFObjectFile::getSectionFileOffsetToRawData(DataRefImpl Sec) const {
440
442}
443
446 DataRefImpl DRI = getSectionByType(SectType);
447
448 if (DRI.p == 0)
449 return 0;
450
451 uint64_t SectionOffset = getSectionFileOffsetToRawData(DRI);
453
454 uintptr_t SectionStart = reinterpret_cast<uintptr_t>(base() + SectionOffset);
460
461 switch (SectType) {
462#define ECASE(Value, String) \
463 case XCOFF::Value: \
464 SectionName = String; \
465 break
466
480#undef ECASE
481 }
483 " section with offset 0x" +
486 " goes past the end of the file");
487 }
488 return SectionStart;
489}
490
492 return false;
493}
494
497}
498
502}
503
507}
508
512}
513
523 auto RelocationsOrErr =
524 relocations<XCOFFSectionHeader64, XCOFFRelocation64>(*SectionEntPtr);
525 if (Error E = RelocationsOrErr.takeError()) {
526
529 }
530 Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().begin());
531 } else {
533 auto RelocationsOrErr =
534 relocations<XCOFFSectionHeader32, XCOFFRelocation32>(*SectionEntPtr);
535 if (Error E = RelocationsOrErr.takeError()) {
536
539 }
540 Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().begin());
541 }
543}
544
549 auto RelocationsOrErr =
550 relocations<XCOFFSectionHeader64, XCOFFRelocation64>(*SectionEntPtr);
551 if (Error E = RelocationsOrErr.takeError()) {
552
555 }
556 Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().end());
557 } else {
559 auto RelocationsOrErr =
560 relocations<XCOFFSectionHeader32, XCOFFRelocation32>(*SectionEntPtr);
561 if (Error E = RelocationsOrErr.takeError()) {
562
565 }
566 Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().end());
567 }
569}
570
573 Rel.p = reinterpret_cast<uintptr_t>(viewAs(Rel.p) + 1);
574 else
575 Rel.p = reinterpret_cast<uintptr_t>(viewAs(Rel.p) + 1);
576}
577
584 for (uint16_t I = 0; I < NumberOfSections; ++I) {
585
586
588 RelocAddress < Sec64->VirtualAddress + Sec64->SectionSize) {
590 }
591 ++Sec64;
592 }
593 } else {
598 for (uint16_t I = 0; I < NumberOfSections; ++I) {
599
600
602 RelocAddress < Sec32->VirtualAddress + Sec32->SectionSize) {
604 }
605 ++Sec32;
606 }
607 }
609}
610
616
619 } else {
622
625 }
629}
630
633 return viewAs(Rel.p)->Type;
634 return viewAs(Rel.p)->Type;
635}
636
643 } else {
646 }
647 Result.append(Res.begin(), Res.end());
648}
649
653
656
660
663
667 if (CsectAuxEntOrErr) {
670 } else
671 return CsectAuxEntOrErr.takeError();
672 }
673
676
677
683
686 }
687 return Result;
688}
689
692 SymDRI.p = reinterpret_cast<uintptr_t>(SymbolTblPtr);
694}
695
701}
702
705}
706
709 DRI.p = getSectionHeaderTableAddress();
711}
712
715 DRI.p = getWithOffset(getSectionHeaderTableAddress(),
718}
719
721
723 return is64Bit() ? "aix5coff64-rs6000" : "aixcoff-rs6000";
724}
725
728}
729
732}
733
738}
739
741 if (AuxiliaryHeader == nullptr)
742 return 0;
743
746}
747
750 .Case("dwinfo", "debug_info")
751 .Case("dwline", "debug_line")
752 .Case("dwpbnms", "debug_pubnames")
753 .Case("dwpbtyp", "debug_pubtypes")
754 .Case("dwarnge", "debug_aranges")
755 .Case("dwabrev", "debug_abbrev")
756 .Case("dwstr", "debug_str")
757 .Case("dwrnges", "debug_ranges")
758 .Case("dwloc", "debug_loc")
759 .Case("dwframe", "debug_frame")
760 .Case("dwmac", "debug_macinfo")
762}
763
764size_t XCOFFObjectFile::getFileHeaderSize() const {
766}
767
768size_t XCOFFObjectFile::getSectionHeaderSize() const {
769 return is64Bit() ? sizeof(XCOFFSectionHeader64) :
770 sizeof(XCOFFSectionHeader32);
771}
772
775}
776
780 uintptr_t StartPtr = reinterpret_cast<uintptr_t>(Start);
781
786 " goes past the end of the file");
788}
789
792}
793
797 "the section index (" + Twine(Num) +
798 ") is invalid");
799
801 DRI.p = getWithOffset(getSectionHeaderTableAddress(),
802 getSectionHeaderSize() * (Num - 1));
803 return DRI;
804}
805
809 auto GetSectionAddr = [&](const auto &Sections) -> uintptr_t {
810 for (const auto &Sec : Sections)
811 if (Sec.getSectionType() == SectType)
812 return reinterpret_cast<uintptr_t>(&Sec);
813 return uintptr_t(0);
814 };
817 else
819 return DRI;
820}
821
822Expected
825
826 switch (SectionNum) {
828 return "N_DEBUG";
830 return "N_ABS";
832 return "N_UNDEF";
833 default:
835 if (SecRef)
837 getSectionNameInternal(SecRef.get()));
839 }
840}
841
845}
846
847bool XCOFFObjectFile::isReservedSectionNumber(int16_t SectionNumber) {
848 return (SectionNumber <= 0 && SectionNumber >= -2);
849}
850
854}
855
858}
859
863}
864
867}
868
870
871
872
874}
875
877 return (fileHeader32()->NumberOfSymTableEntries >= 0
879 : 0);
880}
881
884}
885
888}
889
893}
894
895uintptr_t XCOFFObjectFile::getEndOfSymbolTableAddress() const {
897 return getWithOffset(reinterpret_cast<uintptr_t>(SymbolTblPtr),
899}
900
902 if (SymbolEntPtr < reinterpret_cast<uintptr_t>(SymbolTblPtr))
903 report_fatal_error("Symbol table entry is outside of symbol table.");
904
905 if (SymbolEntPtr >= getEndOfSymbolTableAddress())
906 report_fatal_error("Symbol table entry is outside of symbol table.");
907
908 ptrdiff_t Offset = reinterpret_cast<const char *>(SymbolEntPtr) -
909 reinterpret_cast<const char *>(SymbolTblPtr);
910
913 "Symbol table entry position is not valid inside of symbol table.");
914}
915
917 return (reinterpret_cast<const char *>(SymbolEntPtr) -
918 reinterpret_cast<const char *>(SymbolTblPtr)) /
920}
921
928 if (!CsectAuxRefOrError)
929
931 else {
936 }
937 }
938 return Result;
939}
940
944}
945
949
950 if (Index >= NumberOfSymTableEntries)
952 " exceeds symbol count " +
953 Twine(NumberOfSymTableEntries));
954
958}
959
962}
963
964const char *XCOFFObjectFile::getSectionNameInternal(DataRefImpl Sec) const {
965 return is64Bit() ? toSection64(Sec)->Name : toSection32(Sec)->Name;
966}
967
968uintptr_t XCOFFObjectFile::getSectionHeaderTableAddress() const {
969 return reinterpret_cast<uintptr_t>(SectionHeaderTable);
970}
971
973 return is64Bit() ? toSection64(Sec)->Flags : toSection32(Sec)->Flags;
974}
975
976XCOFFObjectFile::XCOFFObjectFile(unsigned int Type, MemoryBufferRef Object)
979}
980
982 assert(is64Bit() && "64-bit interface called for non 64-bit file.");
986}
987
989 assert(() && "32-bit interface called for non 32-bit file.");
993}
994
995
996
997
998
999template
1002 const T &Section = static_cast<const T &>(Sec);
1004 return Section.NumberOfRelocations;
1005
1006 uint16_t SectionIndex = &Section - sectionHeaderTable() + 1;
1008 return Section.NumberOfRelocations;
1009 for (const auto &Sec : sections32()) {
1011 Sec.NumberOfRelocations == SectionIndex)
1012 return Sec.PhysicalAddress;
1013 }
1015}
1016
1017template <typename Shdr, typename Reloc>
1019 uintptr_t RelocAddr = getWithOffset(reinterpret_cast<uintptr_t>(FileHeader),
1020 Sec.FileOffsetToRelocationInfo);
1022 if (Error E = NumRelocEntriesOrErr.takeError())
1023 return std::move(E);
1024
1025 uint32_t NumRelocEntries = NumRelocEntriesOrErr.get();
1028 "Relocation structure is incorrect");
1029 auto RelocationOrErr =
1030 getObject(Data, reinterpret_cast<void *>(RelocAddr),
1031 NumRelocEntries * sizeof(Reloc));
1032 if (!RelocationOrErr)
1034 toString(RelocationOrErr.takeError()) + ": relocations with offset 0x" +
1035 Twine::utohexstr(Sec.FileOffsetToRelocationInfo) + " and size 0x" +
1037 " go past the end of the file");
1038
1039 const Reloc *StartReloc = RelocationOrErr.get();
1040
1041 return ArrayRef(StartReloc, StartReloc + NumRelocEntries);
1042}
1043
1044template
1048
1051 if (!ExceptionSectOrErr)
1052 return ExceptionSectOrErr.takeError();
1053
1055 if (DRI.p == 0)
1057
1058 ExceptEnt *ExceptEntStart =
1059 reinterpret_cast<ExceptEnt *>(*ExceptionSectOrErr);
1061 ExceptEntStart, ExceptEntStart + getSectionSize(DRI) / sizeof(ExceptEnt));
1062}
1063
1068
1071
1072
1074 Obj->Data, reinterpret_cast<uintptr_t>(Obj->base() + Offset), 4)) {
1077 }
1078
1079
1081
1082
1083
1084 if (Size <= 4)
1085 return XCOFFStringTable{4, nullptr};
1086
1087 auto StringTableOrErr =
1089 if (!StringTableOrErr)
1091 ": string table with offset 0x" +
1094 " goes past the end of the file");
1095
1096 const char *StringTablePtr = StringTableOrErr.get();
1097 if (StringTablePtr[Size - 1] != '\0')
1099
1100 return XCOFFStringTable{Size, StringTablePtr};
1101}
1102
1103
1104
1108 if (!LoaderSectionAddrOrError)
1109 return LoaderSectionAddrOrError.takeError();
1110
1111 uintptr_t LoaderSectionAddr = LoaderSectionAddrOrError.get();
1112 if (!LoaderSectionAddr)
1114
1115 uint64_t OffsetToImportFileTable = 0;
1116 uint64_t LengthOfImportFileTable = 0;
1119 viewAs(LoaderSectionAddr);
1120 OffsetToImportFileTable = LoaderSec64->OffsetToImpid;
1122 } else {
1124 viewAs(LoaderSectionAddr);
1125 OffsetToImportFileTable = LoaderSec32->OffsetToImpid;
1127 }
1128
1129 auto ImportTableOrErr = getObject(
1131 reinterpret_cast<void *>(LoaderSectionAddr + OffsetToImportFileTable),
1132 LengthOfImportFileTable);
1133 if (!ImportTableOrErr)
1135 toString(ImportTableOrErr.takeError()) +
1136 ": import file table with offset 0x" +
1137 Twine::utohexstr(LoaderSectionAddr + OffsetToImportFileTable) +
1138 " and size 0x" + Twine::utohexstr(LengthOfImportFileTable) +
1139 " goes past the end of the file");
1140
1141 const char *ImportTablePtr = ImportTableOrErr.get();
1142 if (ImportTablePtr[LengthOfImportFileTable - 1] != '\0')
1144 ": import file name table with offset 0x" +
1145 Twine::utohexstr(LoaderSectionAddr + OffsetToImportFileTable) +
1146 " and size 0x" + Twine::utohexstr(LengthOfImportFileTable) +
1147 " must end with a null terminator");
1148
1149 return StringRef(ImportTablePtr, LengthOfImportFileTable);
1150}
1151
1154
1155 std::unique_ptr Obj;
1157
1159 const auto *Base = Obj->base();
1161
1162
1163 auto FileHeaderOrErr =
1164 getObject(Data, Base + CurOffset, Obj->getFileHeaderSize());
1165 if (Error E = FileHeaderOrErr.takeError())
1166 return std::move(E);
1167 Obj->FileHeader = FileHeaderOrErr.get();
1168
1169 CurOffset += Obj->getFileHeaderSize();
1170
1171 if (Obj->getOptionalHeaderSize()) {
1172 auto AuxiliaryHeaderOrErr =
1173 getObject(Data, Base + CurOffset, Obj->getOptionalHeaderSize());
1174 if (Error E = AuxiliaryHeaderOrErr.takeError())
1175 return std::move(E);
1176 Obj->AuxiliaryHeader = AuxiliaryHeaderOrErr.get();
1177 }
1178
1179 CurOffset += Obj->getOptionalHeaderSize();
1180
1181
1182 if (Obj->getNumberOfSections()) {
1183 uint64_t SectionHeadersSize =
1184 Obj->getNumberOfSections() * Obj->getSectionHeaderSize();
1185 auto SecHeadersOrErr =
1186 getObject(Data, Base + CurOffset, SectionHeadersSize);
1187 if (!SecHeadersOrErr)
1189 ": section headers with offset 0x" +
1192 " go past the end of the file");
1193
1194 Obj->SectionHeaderTable = SecHeadersOrErr.get();
1195 }
1196
1197 const uint32_t NumberOfSymbolTableEntries =
1198 Obj->getNumberOfSymbolTableEntries();
1199
1200
1201 if (NumberOfSymbolTableEntries == 0)
1202 return std::move(Obj);
1203
1204
1205 CurOffset = Obj->is64Bit() ? Obj->getSymbolTableOffset64()
1206 : Obj->getSymbolTableOffset32();
1207 const uint64_t SymbolTableSize =
1209 NumberOfSymbolTableEntries;
1210 auto SymTableOrErr =
1211 getObject<void *>(Data, Base + CurOffset, SymbolTableSize);
1212 if (!SymTableOrErr)
1214 toString(SymTableOrErr.takeError()) + ": symbol table with offset 0x" +
1216 Twine::utohexstr(SymbolTableSize) + " goes past the end of the file");
1217
1218 Obj->SymbolTblPtr = SymTableOrErr.get();
1219 CurOffset += SymbolTableSize;
1220
1221
1222 Expected StringTableOrErr =
1223 parseStringTable(Obj.get(), CurOffset);
1224 if (Error E = StringTableOrErr.takeError())
1225 return std::move(E);
1226 Obj->StringTable = StringTableOrErr.get();
1227
1228 return std::move(Obj);
1229}
1230
1231Expected<std::unique_ptr>
1233 unsigned FileType) {
1234 return XCOFFObjectFile::create(FileType, MemBufRef);
1235}
1236
1239}
1240
1243 return false;
1244
1246 return true;
1247
1249 if (!ExpCsectAuxEnt)
1250 return ExpCsectAuxEnt.takeError();
1251
1253
1256 return false;
1257
1258
1259
1262 return false;
1263
1264
1265
1266
1268
1269
1270
1271
1272
1273
1275 return false;
1276
1278
1279
1280 if (++NextIt == getObject()->symbol_end())
1281 return true;
1282
1284 return true;
1285
1286
1288 if (!NextCsectAuxEnt)
1289 return NextCsectAuxEnt.takeError();
1290
1292 return false;
1293
1294 return true;
1295 }
1296
1298 return true;
1299
1301 "symbol csect aux entry with index " +
1303 " has invalid symbol type " +
1305}
1306
1311}
1312
1315 "Calling csect symbol interface with a non-csect symbol.");
1316
1318
1320 if (auto Err = NameOrErr.takeError())
1321 return std::move(Err);
1322
1324 if (!NumberOfAuxEntries) {
1325 return createError("csect symbol \"" + *NameOrErr + "\" with index " +
1326 Twine(SymbolIdx) + " contains no auxiliary entry");
1327 }
1328
1329 if (!getObject()->is64Bit()) {
1330
1331
1334 return XCOFFCsectAuxRef(viewAs(AuxAddr));
1335 }
1336
1337
1338
1342 if (*getObject()->getSymbolAuxType(AuxAddr) ==
1344#ifndef NDEBUG
1346#endif
1347 return XCOFFCsectAuxRef(viewAs(AuxAddr));
1348 }
1349 }
1350
1352 "a csect auxiliary entry has not been found for symbol \"" + *NameOrErr +
1353 "\" with index " + Twine(SymbolIdx));
1354}
1355
1357
1358
1360 return StringRef("Unimplemented Debug Name");
1361
1362 if (!getObject()->is64Bit()) {
1363 if (getSymbol32()->NameInStrTbl.Magic !=
1366
1368 }
1369
1371}
1372
1373
1376
1379
1380template LLVM_EXPORT_TEMPLATE
1385template LLVM_EXPORT_TEMPLATE
1390
1392 if (Bytes.size() < 4)
1393 return false;
1394
1396}
1397
1398#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
1399#define GETVALUEWITHMASKSHIFT(X, S) \
1400 ((Data & (TracebackTable::X)) >> (TracebackTable::S))
1401
1404 TBVectorExt TBTVecExt(TBvectorStrRef, Err);
1405 if (Err)
1406 return std::move(Err);
1407 return TBTVecExt;
1408}
1409
1410TBVectorExt::TBVectorExt(StringRef TBvectorStrRef, Error &Err) {
1414 unsigned ParmsNum =
1416
1420 if (!VecParmsTypeOrError)
1421 Err = VecParmsTypeOrError.takeError();
1422 else
1423 VecParmsInfo = VecParmsTypeOrError.get();
1424}
1425
1428}
1429
1432}
1433
1436}
1437
1440 NumberOfVectorParmsShift);
1441}
1442
1445}
1446#undef GETVALUEWITHMASK
1447#undef GETVALUEWITHMASKSHIFT
1448
1453 if (Err)
1454 return std::move(Err);
1455 return TBT;
1456}
1457
1459 Error &Err, bool Is64Bit)
1460 : TBPtr(Ptr), Is64BitObj(Is64Bit) {
1463 0);
1465
1466
1467 DE.getU64(Cur);
1468
1471 uint32_t ParamsTypeValue = 0;
1472
1473
1474 if (Cur && (FixedParmsNum + FloatingParmsNum) > 0)
1475 ParamsTypeValue = DE.getU32(Cur);
1476
1478 TraceBackTableOffset = DE.getU32(Cur);
1479
1481 HandlerMask = DE.getU32(Cur);
1482
1484 NumOfCtlAnchors = DE.getU32(Cur);
1485 if (Cur && NumOfCtlAnchors) {
1487 Disp.reserve(*NumOfCtlAnchors);
1488 for (uint32_t I = 0; I < NumOfCtlAnchors && Cur; ++I)
1490 if (Cur)
1491 ControlledStorageInfoDisp = std::move(Disp);
1492 }
1493 }
1494
1496 uint16_t FunctionNameLen = DE.getU16(Cur);
1497 if (Cur)
1498 FunctionName = DE.getBytes(Cur, FunctionNameLen);
1499 }
1500
1502 AllocaRegister = DE.getU8(Cur);
1503
1504 unsigned VectorParmsNum = 0;
1506 StringRef VectorExtRef = DE.getBytes(Cur, 6);
1507 if (Cur) {
1508 Expected TBVecExtOrErr = TBVectorExt::create(VectorExtRef);
1509 if (!TBVecExtOrErr) {
1510 Err = TBVecExtOrErr.takeError();
1511 return;
1512 }
1513 VecExt = TBVecExtOrErr.get();
1514 VectorParmsNum = VecExt->getNumberOfVectorParms();
1515
1516 DE.skip(Cur, 2);
1517 }
1518 }
1519
1520
1521
1522
1523 if (Cur && (FixedParmsNum + FloatingParmsNum) > 0) {
1524 Expected<SmallString<32>> ParmsTypeOrError =
1527 FloatingParmsNum, VectorParmsNum)
1528 : parseParmsType(ParamsTypeValue, FixedParmsNum, FloatingParmsNum);
1529
1530 if (!ParmsTypeOrError) {
1531 Err = ParmsTypeOrError.takeError();
1532 return;
1533 }
1534 ParmsType = ParmsTypeOrError.get();
1535 }
1536
1538 ExtensionTable = DE.getU8(Cur);
1539
1540 if (*ExtensionTable & ExtendedTBTableFlag::TB_EH_INFO) {
1541
1542 Cur.seek(alignTo(Cur.tell(), 4));
1543 EhInfoDisp = Is64BitObj ? DE.getU64(Cur) : DE.getU32(Cur);
1544 }
1545 }
1546 if (!Cur)
1547 Err = Cur.takeError();
1548
1549 Size = Cur.tell();
1550}
1551
1552#define GETBITWITHMASK(P, X) \
1553 (support::endian::read32be(TBPtr + (P)) & (TracebackTable::X))
1554#define GETBITWITHMASKSHIFT(P, X, S) \
1555 ((support::endian::read32be(TBPtr + (P)) & (TracebackTable::X)) >> \
1556 (TracebackTable::S))
1557
1560}
1561
1564}
1565
1568}
1569
1571 return GETBITWITHMASK(0, IsOutOfLineEpilogOrPrologueMask);
1572}
1573
1575 return GETBITWITHMASK(0, HasTraceBackTableOffsetMask);
1576}
1577
1580}
1581
1584}
1585
1588}
1589
1591 return GETBITWITHMASK(0, IsFloatingPointPresentMask);
1592}
1593
1595 return GETBITWITHMASK(0, IsFloatingPointOperationLogOrAbortEnabledMask);
1596}
1597
1600}
1601
1603 return GETBITWITHMASK(0, IsFunctionNamePresentMask);
1604}
1605
1608}
1609
1612 OnConditionDirectiveShift);
1613}
1614
1617}
1618
1621}
1622
1625}
1626
1629}
1630
1633}
1634
1637}
1638
1641}
1642
1645}
1646
1649 NumberOfFixedParmsShift);
1650}
1651
1654 NumberOfFloatingPointParmsShift);
1655}
1656
1659}
1660
1661#undef GETBITWITHMASK
1662#undef GETBITWITHMASKSHIFT
1663}
1664}
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static bool is64Bit(const char *name)
#define GETVALUEWITHMASKSHIFT(X, S)
#define GETVALUEWITHMASK(X)
#define GETBITWITHMASKSHIFT(P, X, S)
#define GETBITWITHMASK(P, X)
#define ECASE(Value, String)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Helper for Errors used as out-parameters.
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.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
A table of densely packed, null-terminated strings indexed by offset.
Manages the enabling and disabling of subtarget specific features.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Twine utohexstr(const uint64_t &Val)
void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
The instances of the Type class are immutable: once they are created, they are never changed.
A range adaptor for a pair of iterators.
unsigned int getType() const
static Error checkOffset(MemoryBufferRef M, uintptr_t Addr, const uint64_t Size)
This class is the base class for all object file types.
friend class RelocationRef
const uint8_t * base() const
static Expected< std::unique_ptr< ObjectFile > > createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType)
This is a value type class that represents a single symbol in the list of symbols in the object file.
Expected< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
uint8_t getNumberOfVectorParms() const
static Expected< TBVectorExt > create(StringRef TBvectorStrRef)
bool isVRSavedOnStack() const
uint8_t getNumberOfVRSaved() const
bool hasVMXInstruction() const
XCOFF::StorageMappingClass getStorageMappingClass() const
uint8_t getSymbolType() const
uintptr_t getEntryAddress() const
uint64_t getSectionOrLength() const
Expected< DataRefImpl > getSectionByNum(int16_t Num) const
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
const void * getPointerToSymbolTable() const
section_iterator section_begin() const override
uint32_t getSymbolIndex(uintptr_t SymEntPtr) const
relocation_iterator section_rel_end(DataRefImpl Sec) const override
Expected< StringRef > getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const
uintptr_t getSymbolEntryAddressByIndex(uint32_t SymbolTableIndex) const
bool isDebugSection(DataRefImpl Sec) const override
const XCOFFAuxiliaryHeader32 * auxiliaryHeader32() const
ArrayRef< XCOFFSectionHeader32 > sections32() const
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
const XCOFFFileHeader64 * fileHeader64() const
ArrayRef< XCOFFSectionHeader64 > sections64() const
Expected< uint64_t > getStartAddress() const override
Expected< ArrayRef< ExceptEnt > > getExceptionEntries() const
Expected< uint32_t > getSymbolFlags(DataRefImpl Symb) const override
uint32_t getSymbolTableOffset32() const
bool isSectionVirtual(DataRefImpl Sec) const override
bool isSectionBSS(DataRefImpl Sec) const override
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
uint32_t getNumberOfSymbolTableEntries() const
bool isSectionData(DataRefImpl Sec) const override
uint64_t getRelocationOffset(DataRefImpl Rel) const override
uint64_t getSectionSize(DataRefImpl Sec) const override
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
int32_t getSectionFlags(DataRefImpl Sec) const
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
const XCOFFFileHeader32 * fileHeader32() const
int32_t getRawNumberOfSymbolTableEntries32() const
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
uint32_t getNumberOfSymbolTableEntries64() const
iterator_range< xcoff_symbol_iterator > xcoff_symbol_iterator_range
const XCOFFAuxiliaryHeader64 * auxiliaryHeader64() const
uint16_t getOptionalHeaderSize() const
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
XCOFFSymbolRef toSymbolRef(DataRefImpl Ref) const
basic_symbol_iterator symbol_begin() const override
Expected< StringRef > getSymbolNameByIndex(uint32_t SymbolTableIndex) const
unsigned getSymbolSectionID(SymbolRef Sym) const
uint64_t getSymbolTableOffset64() const
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override
uint16_t getNumberOfSections() const
void moveRelocationNext(DataRefImpl &Rel) const override
Expected< StringRef > getImportFileTable() const
StringRef getFileFormatName() const override
Expected< uint32_t > getNumberOfRelocationEntries(const XCOFFSectionHeader< T > &Sec) const
bool isSectionCompressed(DataRefImpl Sec) const override
Expected< StringRef > getSymbolSectionName(XCOFFSymbolRef Ref) const
Expected< StringRef > getStringTableEntry(uint32_t Offset) const
static constexpr uint64_t InvalidRelocOffset
uint64_t getSectionAddress(DataRefImpl Sec) const override
Expected< ArrayRef< uint8_t > > getSectionContents(DataRefImpl Sec) const override
Expected< SubtargetFeatures > getFeatures() const override
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
uint16_t getMagic() const
uint64_t getSectionAlignment(DataRefImpl Sec) const override
void checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const
StringRef mapDebugSectionName(StringRef Name) const override
Maps a debug section name to a standard DWARF section name.
basic_symbol_iterator symbol_end() const override
static uintptr_t getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress, uint32_t Distance)
bool is64Bit() const override
const XCOFF::SymbolAuxType * getSymbolAuxType(uintptr_t AuxEntryAddress) const
Triple::ArchType getArch() const override
uint64_t getRelocationType(DataRefImpl Rel) const override
std::optional< StringRef > tryGetCPUName() const override
bool isSectionText(DataRefImpl Sec) const override
Expected< StringRef > getRawData(const char *Start, uint64_t Size, StringRef Name) const
uint16_t getFlags() const
uint64_t getSymbolSize(DataRefImpl Symb) const
int32_t getTimeStamp() const
void moveSymbolNext(DataRefImpl &Symb) const override
Expected< ArrayRef< Reloc > > relocations(const Shdr &Sec) const
uint64_t getSectionIndex(DataRefImpl Sec) const override
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
void moveSectionNext(DataRefImpl &Sec) const override
Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override
section_iterator section_end() const override
uint32_t getLogicalNumberOfSymbolTableEntries32() const
xcoff_symbol_iterator_range symbols() const
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
StringRef getStringTable() const
Expected< XCOFFCsectAuxRef > getXCOFFCsectAuxRef() const
Expected< bool > isFunction() const
int16_t getSectionNumber() const
bool isCsectSymbol() const
const XCOFFSymbolEntry64 * getSymbol64() const
const XCOFFSymbolEntry32 * getSymbol32() const
uint16_t getSymbolType() const
uint64_t getValue() const
Expected< StringRef > getName() const
uint8_t getNumberOfAuxEntries() const
uintptr_t getEntryAddress() const
XCOFF::StorageClass getStorageClass() const
This class provides methods to extract traceback table data from a buffer.
bool isOutOfLineEpilogOrPrologue() const
uint8_t getNumOfGPRsSaved() const
bool hasTraceBackTableOffset() const
bool hasParmsOnStack() const
bool hasExtensionTable() const
uint8_t getOnConditionDirective() const
uint8_t getLanguageID() const
uint8_t getNumOfFPRsSaved() const
bool isFloatingPointOperationLogOrAbortEnabled() const
uint8_t getNumberOfFPParms() const
bool isFuncNamePresent() const
bool isAllocaUsed() const
bool isGlobalLinkage() const
bool isInternalProcedure() const
bool hasControlledStorage() const
bool isInterruptHandler() const
bool isFloatingPointPresent() const
uint8_t getVersion() const
static Expected< XCOFFTracebackTable > create(const uint8_t *Ptr, uint64_t &Size, bool Is64Bits=false)
Parse an XCOFF Traceback Table from Ptr with Size bytes.
bool isBackChainStored() const
uint8_t getNumberOfFixedParms() const
bool hasVectorInfo() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static constexpr uint8_t XR_BIASED_LENGTH_MASK
constexpr size_t RelocationSerializationSize32
static constexpr uint8_t XR_FIXUP_INDICATOR_MASK
constexpr uint16_t VISIBILITY_MASK
Expected< SmallString< 32 > > parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum, unsigned VectorParmsNum)
static constexpr uint8_t XR_SIGN_INDICATOR_MASK
StringRef getRelocationTypeString(XCOFF::RelocationType Type)
Expected< SmallString< 32 > > parseParmsType(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum)
constexpr size_t RelocationSerializationSize64
Expected< SmallString< 32 > > parseVectorParmsType(uint32_t Value, unsigned ParmsNum)
@ AUX_CSECT
Identifies a csect auxiliary entry.
constexpr size_t NameSize
constexpr uint16_t RelocOverflow
@ XMC_GL
Global Linkage (Interfile Interface Code)
constexpr size_t SymbolTableEntrySize
@ XTY_CM
Common csect definition. For uninitialized storage.
@ XTY_SD
Csect definition for initialized storage.
@ XTY_LD
Label definition.
@ XTY_ER
External reference.
static Expected< const T * > getObject(MemoryBufferRef M, const void *Ptr, const uint64_t Size=sizeof(T))
bool doesXCOFFTracebackTableBegin(ArrayRef< uint8_t > Bytes)
Error createError(const Twine &Err)
Expected< StringRef > getLoaderSecSymNameInStrTbl(const T *LoaderSecHeader, uint64_t Offset)
static const size_t SymbolAuxTypeOffset
static const uint16_t NoRelMask
@ string_table_non_null_end
content_iterator< SectionRef > section_iterator
static const uint8_t FunctionSym
content_iterator< RelocationRef > relocation_iterator
content_iterator< BasicSymbolRef > basic_symbol_iterator
static uintptr_t getWithOffset(uintptr_t Base, ptrdiff_t Offset)
static StringRef generateXCOFFFixedNameStringRef(const char *Name)
static const T * viewAs(uintptr_t in)
uint32_t read32be(const void *P)
uint16_t read16be(const void *P)
This is an optimization pass for GlobalISel generic memory operations.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
@ Ref
The access may reference the value stored in memory.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
const char * toString(DWARFSectionKind Kind)
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
void consumeError(Error Err)
Consume a Error without doing anything.
support::big32_t IsNameInStrTbl
Expected< StringRef > getSymbolName(const LoaderSectionHeader32 *LoaderSecHeader) const
char SymbolName[XCOFF::NameSize]
Expected< StringRef > getSymbolName(const LoaderSectionHeader64 *LoaderSecHeader) const
NameInStrTblType NameInStrTbl
char Name[XCOFF::NameSize+XCOFF::FileNamePadSize]
XCOFF::RelocationType Type
AddressType VirtualAddress
bool isFixupIndicated() const
support::ubig32_t SymbolIndex
uint8_t getRelocatedLength() const
bool isRelocationSigned() const