LLVM: lib/Object/XCOFFObjectFile.cpp Source File (original) (raw)
527 auto RelocationsOrErr =
529 if (Error E = RelocationsOrErr.takeError()) {
530
533 }
534 Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().begin());
535 } else {
537 auto RelocationsOrErr =
539 if (Error E = RelocationsOrErr.takeError()) {
540
543 }
544 Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().begin());
545 }
547}
548
553 auto RelocationsOrErr =
555 if (Error E = RelocationsOrErr.takeError()) {
556
559 }
560 Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().end());
561 } else {
563 auto RelocationsOrErr =
565 if (Error E = RelocationsOrErr.takeError()) {
566
569 }
570 Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().end());
571 }
573}
574
581
586 const uint64_t RelocAddress = Reloc->VirtualAddress;
588 for (uint16_t I = 0; I < NumberOfSections; ++I) {
589
590
592 RelocAddress < Sec64->VirtualAddress + Sec64->SectionSize) {
594 }
595 ++Sec64;
596 }
597 } else {
600 const uint32_t RelocAddress = Reloc->VirtualAddress;
602 for (uint16_t I = 0; I < NumberOfSections; ++I) {
603
604
606 RelocAddress < Sec32->VirtualAddress + Sec32->SectionSize) {
608 }
609 ++Sec32;
610 }
611 }
613}
614
619 Index = Reloc->SymbolIndex;
620
623 } else {
625 Index = Reloc->SymbolIndex;
626
629 }
633}
634
640
647 } else {
650 }
651 Result.append(Res.begin(), Res.end());
652}
653
657
660
664
667
671 if (CsectAuxEntOrErr) {
674 } else
675 return CsectAuxEntOrErr.takeError();
676 }
677
680
681
687
690 }
691 return Result;
692}
693
696 SymDRI.p = reinterpret_cast<uintptr_t>(SymbolTblPtr);
698}
699
706
710
713 DRI.p = getSectionHeaderTableAddress();
715}
716
723
725
727 return is64Bit() ? "aix5coff64-rs6000" : "aixcoff-rs6000";
728}
729
733
737
743
745 if (AuxiliaryHeader == nullptr)
746 return 0;
747
750}
751
754 .Case("dwinfo", "debug_info")
755 .Case("dwline", "debug_line")
756 .Case("dwpbnms", "debug_pubnames")
757 .Case("dwpbtyp", "debug_pubtypes")
758 .Case("dwarnge", "debug_aranges")
759 .Case("dwabrev", "debug_abbrev")
760 .Case("dwstr", "debug_str")
761 .Case("dwrnges", "debug_ranges")
762 .Case("dwloc", "debug_loc")
763 .Case("dwframe", "debug_frame")
764 .Case("dwmac", "debug_macinfo")
766}
767
768size_t XCOFFObjectFile::getFileHeaderSize() const {
770}
771
772size_t XCOFFObjectFile::getSectionHeaderSize() const {
773 return is64Bit() ? sizeof(XCOFFSectionHeader64) :
774 sizeof(XCOFFSectionHeader32);
775}
776
780
784 uintptr_t StartPtr = reinterpret_cast<uintptr_t>(Start);
785
790 " goes past the end of the file");
792}
793
797
801 "the section index (" + Twine(Num) +
802 ") is invalid");
803
805 DRI.p = getWithOffset(getSectionHeaderTableAddress(),
806 getSectionHeaderSize() * (Num - 1));
807 return DRI;
808}
809
813 auto GetSectionAddr = [&](const auto &Sections) -> uintptr_t {
814 for (const auto &Sec : Sections)
815 if (Sec.getSectionType() == SectType)
816 return reinterpret_cast<uintptr_t>(&Sec);
817 return uintptr_t(0);
818 };
821 else
823 return DRI;
824}
825
826Expected
829
830 switch (SectionNum) {
832 return "N_DEBUG";
834 return "N_ABS";
836 return "N_UNDEF";
837 default:
839 if (SecRef)
841 getSectionNameInternal(SecRef.get()));
843 }
844}
845
850
851bool XCOFFObjectFile::isReservedSectionNumber(int16_t SectionNumber) {
852 return (SectionNumber <= 0 && SectionNumber >= -2);
853}
854
859
863
868
872
879
881 return (fileHeader32()->NumberOfSymTableEntries >= 0
883 : 0);
884}
885
889
893
898
899uintptr_t XCOFFObjectFile::getEndOfSymbolTableAddress() const {
901 return getWithOffset(reinterpret_cast<uintptr_t>(SymbolTblPtr),
903}
904
906 if (SymbolEntPtr < reinterpret_cast<uintptr_t>(SymbolTblPtr))
907 report_fatal_error("Symbol table entry is outside of symbol table.");
908
909 if (SymbolEntPtr >= getEndOfSymbolTableAddress())
910 report_fatal_error("Symbol table entry is outside of symbol table.");
911
912 ptrdiff_t Offset = reinterpret_cast<const char *>(SymbolEntPtr) -
913 reinterpret_cast<const char *>(SymbolTblPtr);
914
917 "Symbol table entry position is not valid inside of symbol table.");
918}
919
921 return (reinterpret_cast<const char *>(SymbolEntPtr) -
922 reinterpret_cast<const char *>(SymbolTblPtr)) /
924}
925
932 if (!CsectAuxRefOrError)
933
935 else {
940 }
941 }
942 return Result;
943}
944
949
953
954 if (Index >= NumberOfSymTableEntries)
956 " exceeds symbol count " +
957 Twine(NumberOfSymTableEntries));
958
962}
963
967
968const char *XCOFFObjectFile::getSectionNameInternal(DataRefImpl Sec) const {
969 return is64Bit() ? toSection64(Sec)->Name : toSection32(Sec)->Name;
970}
971
972uintptr_t XCOFFObjectFile::getSectionHeaderTableAddress() const {
973 return reinterpret_cast<uintptr_t>(SectionHeaderTable);
974}
975
977 return is64Bit() ? toSection64(Sec)->Flags : toSection32(Sec)->Flags;
978}
979
980XCOFFObjectFile::XCOFFObjectFile(unsigned int Type, MemoryBufferRef Object)
983}
984
986 assert(is64Bit() && "64-bit interface called for non 64-bit file.");
990}
991
993 assert(() && "32-bit interface called for non 32-bit file.");
997}
998
999
1000
1001
1002
1003template
1006 const T &Section = static_cast<const T &>(Sec);
1008 return Section.NumberOfRelocations;
1009
1010 uint16_t SectionIndex = &Section - sectionHeaderTable() + 1;
1012 return Section.NumberOfRelocations;
1013 for (const auto &Sec : sections32()) {
1015 Sec.NumberOfRelocations == SectionIndex)
1016 return Sec.PhysicalAddress;
1017 }
1019}
1020
1021template <typename Shdr, typename Reloc>
1023 uintptr_t RelocAddr = getWithOffset(reinterpret_cast<uintptr_t>(FileHeader),
1024 Sec.FileOffsetToRelocationInfo);
1026 if (Error E = NumRelocEntriesOrErr.takeError())
1027 return std::move(E);
1028
1029 uint32_t NumRelocEntries = NumRelocEntriesOrErr.get();
1032 "Relocation structure is incorrect");
1033 auto RelocationOrErr =
1035 NumRelocEntries * sizeof(Reloc));
1036 if (!RelocationOrErr)
1038 toString(RelocationOrErr.takeError()) + ": relocations with offset 0x" +
1039 Twine::utohexstr(Sec.FileOffsetToRelocationInfo) + " and size 0x" +
1041 " go past the end of the file");
1042
1043 const Reloc *StartReloc = RelocationOrErr.get();
1044
1045 return ArrayRef(StartReloc, StartReloc + NumRelocEntries);
1046}
1047
1048template
1052
1055 if (!ExceptionSectOrErr)
1056 return ExceptionSectOrErr.takeError();
1057
1059 if (DRI.p == 0)
1061
1062 ExceptEnt *ExceptEntStart =
1063 reinterpret_cast<ExceptEnt *>(*ExceptionSectOrErr);
1065 ExceptEntStart, ExceptEntStart + getSectionSize(DRI) / sizeof(ExceptEnt));
1066}
1067
1072
1075
1076
1078 Obj->Data, reinterpret_cast<uintptr_t>(Obj->base() + Offset), 4)) {
1081 }
1082
1083
1085
1086
1087
1088 if (Size <= 4)
1089 return XCOFFStringTable{4, nullptr};
1090
1091 auto StringTableOrErr =
1093 if (!StringTableOrErr)
1095 ": string table with offset 0x" +
1098 " goes past the end of the file");
1099
1100 const char *StringTablePtr = StringTableOrErr.get();
1101 if (StringTablePtr[Size - 1] != '\0')
1103
1104 return XCOFFStringTable{Size, StringTablePtr};
1105}
1106
1107
1108
1112 if (!LoaderSectionAddrOrError)
1113 return LoaderSectionAddrOrError.takeError();
1114
1115 uintptr_t LoaderSectionAddr = LoaderSectionAddrOrError.get();
1116 if (!LoaderSectionAddr)
1118
1119 uint64_t OffsetToImportFileTable = 0;
1120 uint64_t LengthOfImportFileTable = 0;
1124 OffsetToImportFileTable = LoaderSec64->OffsetToImpid;
1126 } else {
1129 OffsetToImportFileTable = LoaderSec32->OffsetToImpid;
1131 }
1132
1135 reinterpret_cast<void *>(LoaderSectionAddr + OffsetToImportFileTable),
1136 LengthOfImportFileTable);
1137 if (!ImportTableOrErr)
1139 toString(ImportTableOrErr.takeError()) +
1140 ": import file table with offset 0x" +
1141 Twine::utohexstr(LoaderSectionAddr + OffsetToImportFileTable) +
1142 " and size 0x" + Twine::utohexstr(LengthOfImportFileTable) +
1143 " goes past the end of the file");
1144
1145 const char *ImportTablePtr = ImportTableOrErr.get();
1146 if (ImportTablePtr[LengthOfImportFileTable - 1] != '\0')
1148 ": import file name table with offset 0x" +
1149 Twine::utohexstr(LoaderSectionAddr + OffsetToImportFileTable) +
1150 " and size 0x" + Twine::utohexstr(LengthOfImportFileTable) +
1151 " must end with a null terminator");
1152
1153 return StringRef(ImportTablePtr, LengthOfImportFileTable);
1154}
1155
1158
1159 std::unique_ptr Obj;
1161
1163 const auto *Base = Obj->base();
1165
1166
1167 auto FileHeaderOrErr =
1169 if (Error E = FileHeaderOrErr.takeError())
1170 return std::move(E);
1171 Obj->FileHeader = FileHeaderOrErr.get();
1172
1173 CurOffset += Obj->getFileHeaderSize();
1174
1175 if (Obj->getOptionalHeaderSize()) {
1176 auto AuxiliaryHeaderOrErr =
1178 if (Error E = AuxiliaryHeaderOrErr.takeError())
1179 return std::move(E);
1180 Obj->AuxiliaryHeader = AuxiliaryHeaderOrErr.get();
1181 }
1182
1183 CurOffset += Obj->getOptionalHeaderSize();
1184
1185
1186 if (Obj->getNumberOfSections()) {
1187 uint64_t SectionHeadersSize =
1188 Obj->getNumberOfSections() * Obj->getSectionHeaderSize();
1189 auto SecHeadersOrErr =
1191 if (!SecHeadersOrErr)
1193 ": section headers with offset 0x" +
1196 " go past the end of the file");
1197
1198 Obj->SectionHeaderTable = SecHeadersOrErr.get();
1199 }
1200
1201 const uint32_t NumberOfSymbolTableEntries =
1202 Obj->getNumberOfSymbolTableEntries();
1203
1204
1205 if (NumberOfSymbolTableEntries == 0)
1206 return std::move(Obj);
1207
1208
1209 CurOffset = Obj->is64Bit() ? Obj->getSymbolTableOffset64()
1210 : Obj->getSymbolTableOffset32();
1211 const uint64_t SymbolTableSize =
1213 NumberOfSymbolTableEntries;
1214 auto SymTableOrErr =
1216 if (!SymTableOrErr)
1218 toString(SymTableOrErr.takeError()) + ": symbol table with offset 0x" +
1220 Twine::utohexstr(SymbolTableSize) + " goes past the end of the file");
1221
1222 Obj->SymbolTblPtr = SymTableOrErr.get();
1223 CurOffset += SymbolTableSize;
1224
1225
1226 Expected StringTableOrErr =
1227 parseStringTable(Obj.get(), CurOffset);
1228 if (Error E = StringTableOrErr.takeError())
1229 return std::move(E);
1230 Obj->StringTable = StringTableOrErr.get();
1231
1232 return std::move(Obj);
1233}
1234
1235Expected<std::unique_ptr>
1237 unsigned FileType) {
1238 return XCOFFObjectFile::create(FileType, MemBufRef);
1239}
1240
1244
1247 return false;
1248
1250 return true;
1251
1253 if (!ExpCsectAuxEnt)
1254 return ExpCsectAuxEnt.takeError();
1255
1257
1260 return false;
1261
1262
1263
1266 return false;
1267
1268
1269
1270
1272
1273
1274
1275
1276
1277
1279 return false;
1280
1282
1283
1284 if (++NextIt == getObject()->symbol_end())
1285 return true;
1286
1288 return true;
1289
1290
1292 if (!NextCsectAuxEnt)
1293 return NextCsectAuxEnt.takeError();
1294
1296 return false;
1297
1298 return true;
1299 }
1300
1302 return true;
1303
1305 "symbol csect aux entry with index " +
1307 " has invalid symbol type " +
1309}
1310
1316
1319 "Calling csect symbol interface with a non-csect symbol.");
1320
1322
1324 if (auto Err = NameOrErr.takeError())
1325 return std::move(Err);
1326
1328 if (!NumberOfAuxEntries) {
1329 return createError("csect symbol \"" + *NameOrErr + "\" with index " +
1330 Twine(SymbolIdx) + " contains no auxiliary entry");
1331 }
1332
1334
1335
1339 }
1340
1341
1342
1343 for (uint8_t Index = NumberOfAuxEntries; Index > 0; --Index) {
1346 if (*getObject()->getSymbolAuxType(AuxAddr) ==
1348#ifndef NDEBUG
1349 getObject()->checkSymbolEntryPointer(AuxAddr);
1350#endif
1352 }
1353 }
1354
1356 "a csect auxiliary entry has not been found for symbol \"" + *NameOrErr +
1357 "\" with index " + Twine(SymbolIdx));
1358}
1359
1361
1362
1364 return StringRef("Unimplemented Debug Name");
1365
1367 if (getSymbol32()->NameInStrTbl.Magic !=
1370
1371 return getObject()->getStringTableEntry(getSymbol32()->NameInStrTbl.Offset);
1372 }
1373
1375}
1376
1377
1380
1383
1394
1396 if (Bytes.size() < 4)
1397 return false;
1398
1400}
1401
1402#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
1403#define GETVALUEWITHMASKSHIFT(X, S) \
1404 ((Data & (TracebackTable::X)) >> (TracebackTable::S))
1405
1408 TBVectorExt TBTVecExt(TBvectorStrRef, Err);
1409 if (Err)
1410 return std::move(Err);
1411 return TBTVecExt;
1412}
1413
1414TBVectorExt::TBVectorExt(StringRef TBvectorStrRef, Error &Err) {
1415 const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(TBvectorStrRef.data());
1418 unsigned ParmsNum =
1420
1424 if (!VecParmsTypeOrError)
1425 Err = VecParmsTypeOrError.takeError();
1426 else
1427 VecParmsInfo = VecParmsTypeOrError.get();
1428}
1429
1433
1437
1441
1444 NumberOfVectorParmsShift);
1445}
1446
1450#undef GETVALUEWITHMASK
1451#undef GETVALUEWITHMASKSHIFT
1452
1456 XCOFFTracebackTable TBT(Ptr, Size, Err, Is64Bit);
1457 if (Err)
1458 return std::move(Err);
1459 return TBT;
1460}
1461
1462XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
1463 Error &Err, bool Is64Bit)
1464 : TBPtr(Ptr), Is64BitObj(Is64Bit) {
1467 0);
1469
1470
1471 DE.getU64(Cur);
1472
1475 uint32_t ParamsTypeValue = 0;
1476
1477
1478 if (Cur && (FixedParmsNum + FloatingParmsNum) > 0)
1479 ParamsTypeValue = DE.getU32(Cur);
1480
1482 TraceBackTableOffset = DE.getU32(Cur);
1483
1485 HandlerMask = DE.getU32(Cur);
1486
1488 NumOfCtlAnchors = DE.getU32(Cur);
1489 if (Cur && NumOfCtlAnchors) {
1491 Disp.reserve(*NumOfCtlAnchors);
1492 for (uint32_t I = 0; I < NumOfCtlAnchors && Cur; ++I)
1494 if (Cur)
1495 ControlledStorageInfoDisp = std::move(Disp);
1496 }
1497 }
1498
1500 uint16_t FunctionNameLen = DE.getU16(Cur);
1501 if (Cur)
1502 FunctionName = DE.getBytes(Cur, FunctionNameLen);
1503 }
1504
1506 AllocaRegister = DE.getU8(Cur);
1507
1508 unsigned VectorParmsNum = 0;
1510 StringRef VectorExtRef = DE.getBytes(Cur, 6);
1511 if (Cur) {
1512 Expected TBVecExtOrErr = TBVectorExt::create(VectorExtRef);
1513 if (!TBVecExtOrErr) {
1514 Err = TBVecExtOrErr.takeError();
1515 return;
1516 }
1517 VecExt = TBVecExtOrErr.get();
1518 VectorParmsNum = VecExt->getNumberOfVectorParms();
1519
1520 DE.skip(Cur, 2);
1521 }
1522 }
1523
1524
1525
1526
1527 if (Cur && (FixedParmsNum + FloatingParmsNum) > 0) {
1528 Expected<SmallString<32>> ParmsTypeOrError =
1531 FloatingParmsNum, VectorParmsNum)
1532 : parseParmsType(ParamsTypeValue, FixedParmsNum, FloatingParmsNum);
1533
1534 if (!ParmsTypeOrError) {
1535 Err = ParmsTypeOrError.takeError();
1536 return;
1537 }
1538 ParmsType = ParmsTypeOrError.get();
1539 }
1540
1542 ExtensionTable = DE.getU8(Cur);
1543
1544 if (*ExtensionTable & ExtendedTBTableFlag::TB_EH_INFO) {
1545
1546 Cur.seek(alignTo(Cur.tell(), 4));
1547 EhInfoDisp = Is64BitObj ? DE.getU64(Cur) : DE.getU32(Cur);
1548 }
1549 }
1550 if (!Cur)
1551 Err = Cur.takeError();
1552
1553 Size = Cur.tell();
1554}
1555
1556#define GETBITWITHMASK(P, X) \
1557 (support::endian::read32be(TBPtr + (P)) & (TracebackTable::X))
1558#define GETBITWITHMASKSHIFT(P, X, S) \
1559 ((support::endian::read32be(TBPtr + (P)) & (TracebackTable::X)) >> \
1560 (TracebackTable::S))
1561
1565
1569
1573
1577
1581
1585
1589
1593
1597
1599 return GETBITWITHMASK(0, IsFloatingPointOperationLogOrAbortEnabledMask);
1600}
1601
1605
1609
1613
1616 OnConditionDirectiveShift);
1617}
1618
1622
1626
1630
1634
1638
1642
1646
1650
1653 NumberOfFixedParmsShift);
1654}
1655
1658 NumberOfFloatingPointParmsShift);
1659}
1660
1664
1665#undef GETBITWITHMASK
1666#undef GETBITWITHMASKSHIFT
1667}
1668}