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