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(is64Bit() && "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}