59 using namespace dwarf;
62 #define DEBUG_TYPE "dwarf" 70 :
DIContext(CK_DWARF), DWPName(
std::move(DWPName)), DObj(
std::move(DObj)) {}
76 auto *MachO =
dyn_cast<MachOObjectFile>(&Obj);
79 for (
auto LC : MachO->load_commands()) {
81 if (LC.C.cmd == MachO::LC_UUID) {
82 if (LC.C.cmdsize <
sizeof(UUID) +
sizeof(LC.C)) {
83 OS <<
"error: UUID load command is too short.\n";
87 memcpy(&UUID, LC.Ptr+
sizeof(LC.C),
sizeof(UUID));
89 Triple T = MachO->getArchTriple();
91 OS <<
' ' << MachO->getFileName() <<
'\n';
97 std::vector<Optional<StrOffsetsContributionDescriptor>>;
104 for (
const auto &U : Units)
105 Contributions.push_back(U->getStringOffsetsTableContribution());
121 std::unique(Contributions.begin(), Contributions.end(),
128 Contributions.end());
129 return Contributions;
141 for (
auto &Contribution : Contributions) {
144 OS <<
"error: invalid contribution to string offsets table in section ." 145 << SectionName <<
".\n";
150 uint16_t
Version = Contribution->getVersion();
151 uint64_t ContributionHeader = Contribution->Base;
157 ContributionHeader -= Format ==
DWARF32 ? 8 : 16;
160 if (Offset > ContributionHeader) {
161 OS <<
"error: overlapping contributions to string offsets table in " 163 << SectionName <<
".\n";
167 if (Offset < ContributionHeader) {
168 OS <<
format(
"0x%8.8x: Gap, length = ", Offset);
169 OS << (ContributionHeader -
Offset) <<
"\n";
176 OS <<
"Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4))
177 <<
", Format = " << (Format ==
DWARF32 ?
"DWARF32" :
"DWARF64")
178 <<
", Version = " << Version <<
"\n";
180 Offset = Contribution->Base;
181 unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
182 while (Offset - Contribution->Base < Contribution->Size) {
183 OS <<
format(
"0x%8.8x: ", Offset);
185 uint64_t StringOffset =
191 OS <<
format(
"%8.8x ", StringOffset32);
192 const char *S = StrData.
getCStr(&StringOffset32);
194 OS <<
format(
"\"%s\"", S);
196 OS <<
format(
"%16.16" PRIx64
" ", StringOffset);
201 if (Offset < SectionSize) {
202 OS <<
format(
"0x%8.8x: Gap, length = ", Offset);
203 OS << (SectionSize -
Offset) <<
"\n";
218 bool LittleEndian,
unsigned MaxVersion) {
224 StringSection, Units, LittleEndian);
230 if (size & ((uint64_t)(
sizeof(
uint32_t) - 1))) {
231 OS <<
"error: size of ." << SectionName <<
" is not a multiple of " 233 size &= -(uint64_t)
sizeof(
uint32_t);
236 while (offset < size) {
237 OS <<
format(
"0x%8.8x: ", offset);
239 OS <<
format(
"%8.8x ", StringOffset);
240 const char *S = StrData.
getCStr(&StringOffset);
242 OS <<
format(
"\"%s\"", S);
256 if (
Error Err = AddrTable.
extract(AddrData, &Offset, Version, AddrSize,
264 Offset = TableOffset + Length;
266 AddrTable.
dump(OS, DumpOpts);
281 if (
Error Err = Rnglists.
extract(rnglistData, &Offset)) {
283 uint64_t Length = Rnglists.
length();
288 Offset = TableOffset + Length;
290 Rnglists.
dump(OS, LookupPooledAddress, DumpOpts);
308 Header.
dump(OS, DumpOpts);
313 Loclists.
dump(OS, 0, MRI, DumpOffset);
320 uint64_t DumpType = DumpOpts.
DumpType;
323 bool IsDWO = (Extension ==
".dwo") || (Extension ==
".dwp");
326 const auto *ObjFile = DObj->getFile();
333 bool Explicit = DumpType !=
DIDT_All && !IsDWO;
334 bool ExplicitDWO = Explicit && IsDWO;
335 auto shouldDump = [&](
bool Explicit,
const char *
Name,
unsigned ID,
338 bool Should = (DumpType &
Mask) && (Explicit || !
Section.empty());
341 OS <<
"\n" << Name <<
" contents:\n";
342 return &DumpOffsets[
ID];
346 if (shouldDump(Explicit,
".debug_abbrev", DIDT_ID_DebugAbbrev,
347 DObj->getAbbrevSection()))
349 if (shouldDump(ExplicitDWO,
".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
350 DObj->getAbbrevDWOSection()))
354 OS <<
'\n' << Name <<
" contents:\n";
355 if (
auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
356 for (
const auto &U : Units)
357 U->getDIEForOffset(DumpOffset.getValue())
360 for (
const auto &U : Units)
361 U->dump(OS, DumpOpts);
363 if ((DumpType & DIDT_DebugInfo)) {
371 OS <<
'\n' << Name <<
" contents:\n";
372 for (
const auto &U : Units)
373 if (
auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])
374 U->getDIEForOffset(*DumpOffset)
377 U->dump(OS, DumpOpts);
379 if ((DumpType & DIDT_DebugTypes)) {
386 if (
const auto *Off = shouldDump(Explicit,
".debug_loc", DIDT_ID_DebugLoc,
387 DObj->getLocSection().Data)) {
390 if (
const auto *Off =
391 shouldDump(Explicit,
".debug_loclists", DIDT_ID_DebugLoclists,
392 DObj->getLoclistsSection().Data)) {
397 if (
const auto *Off =
398 shouldDump(ExplicitDWO,
".debug_loc.dwo", DIDT_ID_DebugLoc,
399 DObj->getLocDWOSection().Data)) {
403 if (
const auto *Off = shouldDump(Explicit,
".debug_frame", DIDT_ID_DebugFrame,
404 DObj->getDebugFrameSection()))
407 if (
const auto *Off = shouldDump(Explicit,
".eh_frame", DIDT_ID_DebugFrame,
408 DObj->getEHFrameSection()))
411 if (DumpType & DIDT_DebugMacro) {
413 OS <<
"\n.debug_macinfo contents:\n";
418 if (shouldDump(Explicit,
".debug_aranges", DIDT_ID_DebugAranges,
419 DObj->getARangeSection())) {
423 while (
set.
extract(arangesData, &offset))
430 while (!Parser.
done()) {
431 if (DumpOffset && Parser.
getOffset() != *DumpOffset) {
436 if (DumpOpts.Verbose) {
441 LineTable.
dump(OS, DumpOpts);
446 if (
const auto *Off = shouldDump(Explicit,
".debug_line", DIDT_ID_DebugLine,
447 DObj->getLineSection().Data)) {
452 DumpLineSection(Parser, DumpOpts, *Off);
455 if (
const auto *Off =
456 shouldDump(ExplicitDWO,
".debug_line.dwo", DIDT_ID_DebugLine,
457 DObj->getLineDWOSection().Data)) {
462 DumpLineSection(Parser, DumpOpts, *Off);
465 if (shouldDump(Explicit,
".debug_cu_index", DIDT_ID_DebugCUIndex,
466 DObj->getCUIndexSection())) {
470 if (shouldDump(Explicit,
".debug_tu_index", DIDT_ID_DebugTUIndex,
471 DObj->getTUIndexSection())) {
475 if (shouldDump(Explicit,
".debug_str", DIDT_ID_DebugStr,
476 DObj->getStringSection())) {
480 while (
const char *s = strData.getCStr(&offset)) {
481 OS <<
format(
"0x%8.8x: \"%s\"\n", strOffset, s);
485 if (shouldDump(ExplicitDWO,
".debug_str.dwo", DIDT_ID_DebugStr,
486 DObj->getStringDWOSection())) {
490 while (
const char *s = strDWOData.getCStr(&offset)) {
491 OS <<
format(
"0x%8.8x: \"%s\"\n", strDWOOffset, s);
492 strDWOOffset = offset;
495 if (shouldDump(Explicit,
".debug_line_str", DIDT_ID_DebugLineStr,
496 DObj->getLineStringSection())) {
500 while (
const char *s = strData.getCStr(&offset)) {
501 OS <<
format(
"0x%8.8x: \"", strOffset);
508 if (shouldDump(Explicit,
".debug_addr", DIDT_ID_DebugAddr,
509 DObj->getAddrSection().Data)) {
515 if (shouldDump(Explicit,
".debug_ranges", DIDT_ID_DebugRanges,
516 DObj->getRangeSection().Data)) {
522 while (rangesData.isValidOffset(offset)) {
533 auto I = CUs.begin();
536 return (*I)->getAddrOffsetSectionItem(
Index);
539 if (shouldDump(Explicit,
".debug_rnglists", DIDT_ID_DebugRnglists,
540 DObj->getRnglistsSection().Data)) {
546 if (shouldDump(ExplicitDWO,
".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
547 DObj->getRnglistsDWOSection().Data)) {
553 if (shouldDump(Explicit,
".debug_pubnames", DIDT_ID_DebugPubnames,
554 DObj->getPubNamesSection().Data))
558 if (shouldDump(Explicit,
".debug_pubtypes", DIDT_ID_DebugPubtypes,
559 DObj->getPubTypesSection().Data))
563 if (shouldDump(Explicit,
".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
564 DObj->getGnuPubNamesSection().Data))
569 if (shouldDump(Explicit,
".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
570 DObj->getGnuPubTypesSection().Data))
575 if (shouldDump(Explicit,
".debug_str_offsets", DIDT_ID_DebugStrOffsets,
576 DObj->getStringOffsetSection().Data))
578 DObj->getStringOffsetSection(),
581 if (shouldDump(ExplicitDWO,
".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
582 DObj->getStringOffsetDWOSection().Data))
584 DObj->getStringOffsetDWOSection(),
585 DObj->getStringDWOSection(),
dwo_units(),
588 if (shouldDump(Explicit,
".gdb_index", DIDT_ID_GdbIndex,
589 DObj->getGdbIndexSection())) {
593 if (shouldDump(Explicit,
".apple_names", DIDT_ID_AppleNames,
594 DObj->getAppleNamesSection().Data))
597 if (shouldDump(Explicit,
".apple_types", DIDT_ID_AppleTypes,
598 DObj->getAppleTypesSection().Data))
601 if (shouldDump(Explicit,
".apple_namespaces", DIDT_ID_AppleNamespaces,
602 DObj->getAppleNamespacesSection().Data))
605 if (shouldDump(Explicit,
".apple_objc", DIDT_ID_AppleObjC,
606 DObj->getAppleObjCSection().Data))
608 if (shouldDump(Explicit,
".debug_names", DIDT_ID_DebugNames,
609 DObj->getDebugNamesSection().Data))
614 parseDWOUnits(LazyParse);
617 if (
const auto *R = CUI.getFromHash(Hash))
618 return dyn_cast_or_null<DWARFCompileUnit>(
629 if (!DWOCU->getDWOId()) {
631 toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
632 DWOCU->setDWOId(*DWOId);
637 if (DWOCU->getDWOId() == Hash)
638 return dyn_cast<DWARFCompileUnit>(DWOCU.get());
646 return CU->getDIEForOffset(Offset);
655 if (DumpOpts.
DumpType & DIDT_DebugInfo)
657 if (DumpOpts.
DumpType & DIDT_DebugLine)
669 CUIndex = llvm::make_unique<DWARFUnitIndex>(
DW_SECT_INFO);
670 CUIndex->parse(CUIndexData);
681 TUIndex->parse(TUIndexData);
689 DataExtractor GdbIndexData(DObj->getGdbIndexSection(),
true , 0);
690 GdbIndex = llvm::make_unique<DWARFGdbIndex>();
691 GdbIndex->parse(GdbIndexData);
702 Abbrev->extract(abbrData);
708 return AbbrevDWO.get();
712 AbbrevDWO->extract(abbrData);
713 return AbbrevDWO.get();
742 LocDWO->parse(LocData, 4 );
748 return Aranges.get();
751 Aranges->generate(
this);
752 return Aranges.get();
757 return DebugFrame.get();
771 DebugFrame->parse(debugFrameData);
772 return DebugFrame.get();
777 return EHFrame.get();
780 DObj->getAddressSize());
782 DebugFrame->parse(debugFrameData);
783 return DebugFrame.get();
792 Macro->parse(MacinfoData);
796 template <
typename T>
799 bool IsLittleEndian) {
804 Cache.reset(
new T(AccelSection, StrData));
805 if (
Error E = Cache->extract())
811 return getAccelTable(Names, *DObj, DObj->getDebugNamesSection(),
816 return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(),
821 return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(),
827 DObj->getAppleNamespacesSection(),
832 return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(),
840 if (!ExpectedLineTable) {
844 return *ExpectedLineTable;
872 return Line->getOrParseLineTable(lineData, stmtOffset, *
this, U,
873 RecoverableErrorCallback);
876 void DWARFContext::parseNormalUnits() {
877 if (!NormalUnits.
empty())
888 void DWARFContext::parseDWOUnits(
bool Lazy) {
889 if (!DWOUnits.
empty())
891 DObj->forEachInfoDWOSections([&](
const DWARFSection &S) {
895 DObj->forEachTypesDWOSections([&](
const DWARFSection &S) {
902 return dyn_cast_or_null<DWARFCompileUnit>(
923 std::vector<DWARFDie> Worklist;
925 while (!Worklist.empty()) {
929 if (DIE.
getTag() == DW_TAG_lexical_block &&
935 for (
auto Child : DIE)
936 Worklist.push_back(Child);
945 std::string &FunctionName,
952 if (InlinedChain.
empty())
956 bool FoundResult =
false;
957 const char *
Name =
nullptr;
963 StartLine = DeclLineResult;
996 std::string FunctionName =
"<invalid>";
1007 Lines.
push_back(std::make_pair(Address, Result));
1014 std::vector<uint32_t> RowVector;
1018 for (
uint32_t RowIndex : RowVector) {
1041 return InliningInfo;
1046 if (InlinedChain.
size() == 0) {
1057 return InliningInfo;
1060 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
1061 for (
uint32_t i = 0, n = InlinedChain.
size(); i != n; i++) {
1062 DWARFDie &FunctionDIE = InlinedChain[i];
1084 Frame.
Line = CallLine;
1085 Frame.
Column = CallColumn;
1096 return InliningInfo;
1099 std::shared_ptr<DWARFContext>
1101 if (
auto S = DWP.lock()) {
1103 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1106 std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
1108 if (
auto S = Entry->lock()) {
1110 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1114 if (!CheckedForDWP) {
1117 this->DWPName.
empty()
1118 ? (DObj->getFileName() +
".dwp").
toStringRef(DWPName)
1124 CheckedForDWP =
true;
1140 auto S = std::make_shared<DWOFile>();
1141 S->File = std::move(Obj.get());
1144 auto *Ctxt = S->Context.get();
1145 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1149 return make_error<StringError>(Reason +
toString(std::move(E)),
1163 const RelocationRef &Reloc,
1165 std::map<SymbolRef, SymInfo> &Cache) {
1170 std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
1175 std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
1177 return CacheIt->second;
1181 return createError(
"failed to compute symbol address: ",
1187 return createError(
"failed to get symbol section: ",
1188 SectOrErr.takeError());
1192 }
else if (
auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
1193 RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
1194 Ret.
Address = RSec->getAddress();
1209 Ret.
Address += SectionLoadAddress - RSec->getAddress();
1211 if (CacheIt != Cache.end())
1212 CacheIt->second = Ret;
1218 const RelocationRef &Reloc) {
1219 const MachOObjectFile *MachObj =
dyn_cast<MachOObjectFile>(&Obj);
1224 auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
1225 return MachObj->isRelocationScattered(RelocInfo);
1238 class DWARFObjInMemory final :
public DWARFObject {
1239 bool IsLittleEndian;
1240 uint8_t AddressSize;
1243 std::vector<SectionName> SectionNames;
1246 std::map<object::SectionRef, unsigned>>;
1248 InfoSectionMap InfoSections;
1249 InfoSectionMap TypesSections;
1250 InfoSectionMap InfoDWOSections;
1251 InfoSectionMap TypesDWOSections;
1253 DWARFSectionMap LocSection;
1254 DWARFSectionMap LocListsSection;
1255 DWARFSectionMap LineSection;
1256 DWARFSectionMap RangeSection;
1257 DWARFSectionMap RnglistsSection;
1258 DWARFSectionMap StringOffsetSection;
1259 DWARFSectionMap LineDWOSection;
1260 DWARFSectionMap LocDWOSection;
1261 DWARFSectionMap StringOffsetDWOSection;
1262 DWARFSectionMap RangeDWOSection;
1263 DWARFSectionMap RnglistsDWOSection;
1264 DWARFSectionMap AddrSection;
1265 DWARFSectionMap AppleNamesSection;
1266 DWARFSectionMap AppleTypesSection;
1267 DWARFSectionMap AppleNamespacesSection;
1268 DWARFSectionMap AppleObjCSection;
1269 DWARFSectionMap DebugNamesSection;
1270 DWARFSectionMap PubNamesSection;
1271 DWARFSectionMap PubTypesSection;
1272 DWARFSectionMap GnuPubNamesSection;
1273 DWARFSectionMap GnuPubTypesSection;
1277 .Case(
"debug_loc", &LocSection)
1278 .
Case(
"debug_loclists", &LocListsSection)
1279 .
Case(
"debug_line", &LineSection)
1280 .
Case(
"debug_str_offsets", &StringOffsetSection)
1281 .
Case(
"debug_ranges", &RangeSection)
1282 .
Case(
"debug_rnglists", &RnglistsSection)
1283 .
Case(
"debug_loc.dwo", &LocDWOSection)
1284 .
Case(
"debug_line.dwo", &LineDWOSection)
1285 .
Case(
"debug_names", &DebugNamesSection)
1286 .
Case(
"debug_rnglists.dwo", &RnglistsDWOSection)
1287 .
Case(
"debug_str_offsets.dwo", &StringOffsetDWOSection)
1288 .
Case(
"debug_addr", &AddrSection)
1289 .
Case(
"apple_names", &AppleNamesSection)
1290 .
Case(
"debug_pubnames", &PubNamesSection)
1291 .
Case(
"debug_pubtypes", &PubTypesSection)
1292 .
Case(
"debug_gnu_pubnames", &GnuPubNamesSection)
1293 .
Case(
"debug_gnu_pubtypes", &GnuPubTypesSection)
1294 .
Case(
"apple_types", &AppleTypesSection)
1295 .
Case(
"apple_namespaces", &AppleNamespacesSection)
1296 .
Case(
"apple_namespac", &AppleNamespacesSection)
1297 .
Case(
"apple_objc", &AppleObjCSection)
1316 std::deque<SmallString<0>> UncompressedSections;
1322 .Case(
"debug_abbrev", &AbbrevSection)
1323 .
Case(
"debug_aranges", &ARangeSection)
1324 .
Case(
"debug_frame", &DebugFrameSection)
1325 .
Case(
"eh_frame", &EHFrameSection)
1326 .
Case(
"debug_str", &StringSection)
1327 .
Case(
"debug_macinfo", &MacinfoSection)
1328 .
Case(
"debug_abbrev.dwo", &AbbrevDWOSection)
1329 .
Case(
"debug_str.dwo", &StringDWOSection)
1330 .
Case(
"debug_cu_index", &CUIndexSection)
1331 .
Case(
"debug_tu_index", &TUIndexSection)
1332 .
Case(
"gdb_index", &GdbIndexSection)
1333 .
Case(
"debug_line_str", &LineStringSection)
1340 Error maybeDecompress(
const object::SectionRef &Sec,
StringRef Name,
1342 if (!Decompressor::isCompressed(Sec))
1346 Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
1351 if (
auto Err = Decompressor->resizeAndDecompress(Out))
1354 UncompressedSections.push_back(std::move(Out));
1355 Data = UncompressedSections.
back();
1361 DWARFObjInMemory(
const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
1362 uint8_t AddrSize,
bool IsLittleEndian)
1363 : IsLittleEndian(IsLittleEndian) {
1364 for (
const auto &SecIt : Sections) {
1365 if (
StringRef *SectionData = mapSectionToMember(SecIt.first()))
1366 *SectionData = SecIt.second->getBuffer();
1367 else if (SecIt.first() ==
"debug_info")
1370 InfoSections[SectionRef()].Data = SecIt.second->getBuffer();
1371 else if (SecIt.first() ==
"debug_info.dwo")
1372 InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
1373 else if (SecIt.first() ==
"debug_types")
1374 TypesSections[SectionRef()].Data = SecIt.second->getBuffer();
1375 else if (SecIt.first() ==
"debug_types.dwo")
1376 TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
1389 ++SectionAmountMap[
Name];
1390 SectionNames.push_back({
Name,
true });
1408 if (
auto Err = maybeDecompress(
Section, Name, Data)) {
1410 "failed to decompress '" + Name +
"', ", std::move(Err)));
1425 if (
StringRef *SectionData = mapSectionToMember(Name)) {
1426 *SectionData =
Data;
1427 if (Name ==
"debug_ranges") {
1429 RangeDWOSection.Data =
Data;
1431 }
else if (Name ==
"debug_info") {
1435 }
else if (Name ==
"debug_info.dwo") {
1437 }
else if (Name ==
"debug_types") {
1439 }
else if (Name ==
"debug_types.dwo") {
1448 RelocatedSection->getName(RelSecName);
1461 if (!L && isa<MachOObjectFile>(&Obj))
1464 RelSecName = RelSecName.
substr(
1469 DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
1474 if (RelSecName ==
"debug_info")
1475 Map = &
static_cast<DWARFSectionMap &
>(InfoSections[*RelocatedSection])
1477 else if (RelSecName ==
"debug_info.dwo")
1478 Map = &
static_cast<DWARFSectionMap &
>(
1479 InfoDWOSections[*RelocatedSection])
1481 else if (RelSecName ==
"debug_types")
1483 &
static_cast<DWARFSectionMap &
>(TypesSections[*RelocatedSection])
1485 else if (RelSecName ==
"debug_types.dwo")
1486 Map = &
static_cast<DWARFSectionMap &
>(
1487 TypesDWOSections[*RelocatedSection])
1497 std::map<SymbolRef, SymInfo> AddrCache;
1498 for (
const RelocationRef &Reloc :
Section.relocations()) {
1506 if (!SymInfoOrErr) {
1513 uint64_t Val = V.
visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
1516 Reloc.getTypeName(Type);
1518 createError(
"failed to compute relocation: " + Type +
", ",
1525 Map->
insert({Reloc.getOffset(), Rel});
1530 if (SectionAmountMap[S.Name] > 1)
1531 S.IsNameUnique =
false;
1535 uint64_t Pos)
const override {
1536 auto &Sec =
static_cast<const DWARFSectionMap &
>(S);
1538 if (AI == Sec.Relocs.end())
1546 return SectionNames;
1550 StringRef getAbbrevDWOSection()
const override {
return AbbrevDWOSection; }
1551 const DWARFSection &getLineDWOSection()
const override {
1552 return LineDWOSection;
1554 const DWARFSection &getLocDWOSection()
const override {
1555 return LocDWOSection;
1557 StringRef getStringDWOSection()
const override {
return StringDWOSection; }
1558 const DWARFSection &getStringOffsetDWOSection()
const override {
1559 return StringOffsetDWOSection;
1561 const DWARFSection &getRangeDWOSection()
const override {
1562 return RangeDWOSection;
1564 const DWARFSection &getRnglistsDWOSection()
const override {
1565 return RnglistsDWOSection;
1567 const DWARFSection &getAddrSection()
const override {
return AddrSection; }
1568 StringRef getCUIndexSection()
const override {
return CUIndexSection; }
1569 StringRef getGdbIndexSection()
const override {
return GdbIndexSection; }
1570 StringRef getTUIndexSection()
const override {
return TUIndexSection; }
1573 const DWARFSection &getStringOffsetSection()
const override {
1574 return StringOffsetSection;
1576 StringRef getLineStringSection()
const override {
return LineStringSection; }
1579 void forEachInfoDWOSections(
1581 for (
auto &
P : InfoDWOSections)
1584 void forEachTypesDWOSections(
1586 for (
auto &
P : TypesDWOSections)
1590 StringRef getAbbrevSection()
const override {
return AbbrevSection; }
1591 const DWARFSection &getLocSection()
const override {
return LocSection; }
1592 const DWARFSection &getLoclistsSection()
const override {
return LocListsSection; }
1593 StringRef getARangeSection()
const override {
return ARangeSection; }
1594 StringRef getDebugFrameSection()
const override {
return DebugFrameSection; }
1595 StringRef getEHFrameSection()
const override {
return EHFrameSection; }
1596 const DWARFSection &getLineSection()
const override {
return LineSection; }
1597 StringRef getStringSection()
const override {
return StringSection; }
1598 const DWARFSection &getRangeSection()
const override {
return RangeSection; }
1599 const DWARFSection &getRnglistsSection()
const override {
1600 return RnglistsSection;
1602 StringRef getMacinfoSection()
const override {
return MacinfoSection; }
1603 const DWARFSection &getPubNamesSection()
const override {
return PubNamesSection; }
1604 const DWARFSection &getPubTypesSection()
const override {
return PubTypesSection; }
1605 const DWARFSection &getGnuPubNamesSection()
const override {
1606 return GnuPubNamesSection;
1608 const DWARFSection &getGnuPubTypesSection()
const override {
1609 return GnuPubTypesSection;
1611 const DWARFSection &getAppleNamesSection()
const override {
1612 return AppleNamesSection;
1614 const DWARFSection &getAppleTypesSection()
const override {
1615 return AppleTypesSection;
1617 const DWARFSection &getAppleNamespacesSection()
const override {
1618 return AppleNamespacesSection;
1620 const DWARFSection &getAppleObjCSection()
const override {
1621 return AppleObjCSection;
1623 const DWARFSection &getDebugNamesSection()
const override {
1624 return DebugNamesSection;
1628 uint8_t getAddressSize()
const override {
return AddressSize; }
1629 void forEachInfoSections(
1631 for (
auto &
P : InfoSections)
1634 void forEachTypesSections(
1636 for (
auto &
P : TypesSections)
1642 std::unique_ptr<DWARFContext>
1645 std::string DWPName) {
1646 auto DObj = llvm::make_unique<DWARFObjInMemory>(Obj, L, HandleError);
1647 return llvm::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName));
1650 std::unique_ptr<DWARFContext>
1654 llvm::make_unique<DWARFObjInMemory>(Sections, AddrSize,
isLittleEndian);
1655 return llvm::make_unique<DWARFContext>(std::move(DObj),
"");
1665 std::string TargetLookupError;
1666 const Target *TheTarget =
1668 if (!TargetLookupError.empty())
1670 TargetLookupError.c_str());
1683 Addr =
CU->getAddressByteSize();
const DWARFUnitIndex & getTUIndex()
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
void getInlinedChainForAddress(uint64_t Address, SmallVectorImpl< DWARFDie > &InlinedChain)
getInlinedChainForAddress - fetches inlined chain for a given address.
const DWARFDebugFrame * getEHFrame()
Get a pointer to the parsed eh frame information object.
const DWARFDebugFrame * getDebugFrame()
Get a pointer to the parsed frame information object.
unsigned getMaxDWOVersion()
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj, const DWARFSection &StringOffsetsSection, StringRef StringSection, DWARFContext::unit_iterator_range Units, bool LittleEndian, unsigned MaxVersion)
uint8_t[16] uuid_t
Output a formatted UUID with dash separators.
static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFDataExtractor Data, const MCRegisterInfo *MRI, Optional< uint64_t > DumpOffset)
unit_iterator_range dwo_type_units()
Get type units in the DWO context.
A parsed .debug_frame or .eh_frame section.
This class represents lattice values for constants.
Represents structure for holding and parsing .debug_pub* tables.
const DWARFDebugLoc * getDebugLoc()
Get a pointer to the parsed DebugLoc object.
virtual bool getLoadedSectionContents(const object::SectionRef &Sec, StringRef &Data) const
If conveniently available, return the content of the given Section.
void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo, Optional< uint64_t > Offset) const
Print the location lists found within the debug_loc section.
ErrorPolicy
Used as a return value for a error callback passed to DWARF context.
bool addressRangeContainsAddress(const uint64_t Address) const
void setVendor(VendorType Kind)
setVendor - Set the vendor (second) component of the triple to a known type.
StringRef getFileName() const
const AppleAcceleratorTable & getAppleNamespaces()
Get a reference to the parsed accelerator table object.
void dump(raw_ostream &OS) const
DWARFDie getDIEForOffset(uint32_t Offset)
Get a DIE given an exact offset.
void push_back(const T &Elt)
DWARFGdbIndex & getGdbIndex()
std::shared_ptr< DWARFContext > getDWOContext(StringRef AbsolutePath)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
static raw_ostream & error()
Convenience method for printing "error: " to stderr.
unsigned getNumDWOCompileUnits()
Get the number of compile units in the DWO context.
uint32_t findAddress(uint64_t Address) const
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
bool handleDebugLine()
Verify the information in the .debug_line section.
An efficient, type-erasing, non-owning reference to a callable.
uint8_t getCUAddrSize()
Get address size from CUs.
uint32_t Line
An unsigned integer indicating a source line number.
DIEsForAddress getDIEsForAddress(uint64_t Address)
Get the compilation unit, the function DIE and lexical block DIE for the given address where applicab...
This class is the base class for all object file types.
virtual std::string message() const
Return the error message as a string.
static raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
This class implements a map that also provides access to all stored values in a deterministic order...
const DWARFDebugLine::LineTable * getLineTableForUnit(DWARFUnit *U)
Get a pointer to a parsed line table corresponding to a compile unit.
unsigned getNumTypeUnits()
Get the number of type units in this context.
unit_iterator_range dwo_info_section_units()
Get units from .debug_info..dwo in the DWO context.
void setOS(OSType Kind)
setOS - Set the operating system (third) component of the triple to a known type. ...
void addFrame(const DILineInfo &Frame)
const DWARFDebugAbbrev * getDebugAbbrevDWO()
Get a pointer to the parsed dwo abbreviations object.
DINameKind
A DINameKind is passed to name search methods to specify a preference regarding the type of name reso...
Error takeError()
Take ownership of the stored error.
static const Target * lookupTarget(const std::string &Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
Base class for error info classes.
void addUnitsForSection(DWARFContext &C, const DWARFSection &Section, DWARFSectionKind SectionKind)
Read units from a .debug_info or .debug_types section.
bool handleDebugInfo()
Verify the information in the .debug_info and .debug_types sections.
raw_ostream & write_uuid(const uuid_t UUID)
A format-neutral container for source line information.
DWARFDie getSubroutineForAddress(uint64_t Address)
Returns subprogram DIE with address range encompassing the provided address.
void dump(raw_ostream &OS, uint64_t BaseAddr, const MCRegisterInfo *RegInfo, Optional< uint64_t > Offset) const
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
amdgpu Simplify well known AMD library false Value Value const Twine & Name
std::string toString(Error E)
Write all error messages (if any) in E to a string.
DWARFCompileUnit * getCompileUnitForOffset(uint32_t Offset)
Return the compile unit that includes an offset (relative to .debug_info).
static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind, std::string &FunctionName, uint32_t &StartLine)
Triple::ArchType getArch() const
static T & getAccelTable(std::unique_ptr< T > &Cache, const DWARFObject &Obj, const DWARFSection &Section, StringRef StringSection, bool IsLittleEndian)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
unit_iterator_range normal_units()
Get all normal compile/type units in this context.
const char * getCompilationDir()
A class representing an address table as specified in DWARF v5.
unsigned getNumCompileUnits()
Get the number of compile units in this context.
const DWARFSection & getLineSection() const
unit_iterator_range compile_units()
Get compile units in this context.
uint64_t Address
The program-counter value corresponding to a machine instruction generated by the compiler...
void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, uint32_t &CallColumn, uint32_t &CallDiscriminator) const
Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column from DIE (or zeroes if the...
virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const
Obtain the Load Address of a section by SectionRef.
Tagged union holding either a T or a Error.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
uint64_t Size
The contribution size not including the header.
const MCRegisterInfo * getRegisterInfo() const
unsigned getNumDWOTypeUnits()
Get the number of type units in the DWO context.
uint8_t getAddressByteSize() const
content_iterator< SectionRef > section_iterator
bool verify(raw_ostream &OS, DIDumpOptions DumpOpts={}) override
const DWARFDebugAranges * getDebugAranges()
Get a pointer to the parsed DebugAranges object.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
const DWARFDebugAbbrev * getDebugAbbrev()
Get a pointer to the parsed DebugAbbrev object.
section_iterator_range sections() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
const std::string & str() const
Analysis containing CSE Info
uint64_t getDeclLine() const
Returns the declaration line (start line) for a DIE, assuming it specifies a subprogram.
Expected< section_iterator > getSection() const
Get section this symbol is defined in reference to.
void dump(raw_ostream &OS, const MCRegisterInfo *MRI, Optional< uint64_t > Offset) const
Dump the section data into the given stream.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Error loadRegisterInfo(const object::ObjectFile &Obj)
Loads register info for the architecture of the provided object file.
Container for dump options that control which debug information will be dumped.
unit_iterator_range info_section_units()
Get units from .debug_info in this context.
virtual StringRef mapDebugSectionName(StringRef Name) const
Maps a debug section name to a standard DWARF section name.
static Expected< StringRef > getFileName(const DebugStringTableSubsectionRef &Strings, const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID)
Optional< uint64_t > toSectionOffset(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
A switch()-like statement whose cases are string literals.
Utility class that carries the DWARF compile/type unit and the debug info entry in an object...
This implements the Apple accelerator table format, a precursor of the DWARF 5 accelerator table form...
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
unit_iterator_range dwo_types_section_units()
Get units from .debug_types.dwo in the DWO context.
unsigned const MachineRegisterInfo * MRI
virtual uint8_t getBytesInAddress() const =0
The number of bytes used to represent an address in this object file format.
const DWARFDebugLoclists * getDebugLocDWO()
Get a pointer to the parsed DebugLoc object.
The instances of the Type class are immutable: once they are created, they are never changed...
Controls which fields of DILineInfo container should be filled with data.
DIDumpOptions noImplicitRecursion() const
Return the options with RecurseDepth set to 0 unless explicitly required.
static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData, DIDumpOptions DumpOpts, uint16_t Version, uint8_t AddrSize)
LineTable parseNext(function_ref< void(Error)> RecoverableErrorCallback, function_ref< void(Error)> UnrecoverableErrorCallback, raw_ostream *OS=nullptr)
Get the next line table from the section.
uint16_t File
An unsigned integer indicating the identity of the source file corresponding to a machine instruction...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
const DWARFDebugMacro * getDebugMacro()
Get a pointer to the parsed DebugMacro object.
A format-neutral container for inlined code description.
A structured debug information entry.
LLVM_NODISCARD size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
void dump(raw_ostream &OS) const
bool handleDebugAbbrev()
Verify the information in any of the following sections, if available: .debug_abbrev, debug_abbrev.dwo.
static void dumpWarning(Error Warning)
Dump Error as warning message to stderr.
static Error createError(const Twine &Reason, llvm::Error E)
DILineInfo getLineInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
static ErrorPolicy defaultErrorHandler(Error E)
Function used to handle default error reporting policy.
MCRegisterInfo * createMCRegInfo(StringRef TT) const
createMCRegInfo - Create a MCRegisterInfo implementation.
Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr, uint16_t Version, uint8_t AddrSize, std::function< void(Error)> WarnCallback)
Extract an entire table, including all addresses.
void dump(raw_ostream &OS)
virtual basic_symbol_iterator symbol_end() const =0
static void dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj, const DWARFSection &StringOffsetsSection, StringRef StringSection, DWARFContext::unit_iterator_range Units, bool LittleEndian)
static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj)
Dump the UUID load command.
static bool isRelocScattered(const object::ObjectFile &Obj, const RelocationRef &Reloc)
void dump(raw_ostream &OS) const
Print the macro list found within the debug_macinfo section.
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
Expected< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
void consumeError(Error Err)
Consume a Error without doing anything.
LLVM_NODISCARD char back() const
back - Get the last character in the string.
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const
DWARFUnit * getUnitForOffset(uint32_t Offset) const
bool isLittleEndian() const
const AppleAcceleratorTable & getAppleObjC()
Get a reference to the parsed accelerator table object.
Triple - Helper class for working with autoconf configuration names.
Standard .debug_line state machine structure.
const AppleAcceleratorTable & getAppleTypes()
Get a reference to the parsed accelerator table object.
static std::unique_ptr< DWARFContext > create(const object::ObjectFile &Obj, const LoadedObjectInfo *L=nullptr, function_ref< ErrorPolicy(Error)> HandleError=defaultErrorHandler, std::string DWPName="")
void sort(IteratorTy Start, IteratorTy End)
DWARFUnit * getUnitForIndexEntry(const DWARFUnitIndex::Entry &E)
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
bool lookupAddressRange(uint64_t Address, uint64_t Size, std::vector< uint32_t > &Result) const
unit_iterator_range dwo_compile_units()
Get compile units in the DWO context.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
.debug_names section consists of one or more units.
DWARFCompileUnit * getDWOCompileUnitForHash(uint64_t Hash)
void dump(raw_ostream &OS, DIDumpOptions DumpOpts={}) const
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
uint16_t Column
An unsigned integer indicating a column number within a source line.
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
StringRef getArchName() const
getArchName - Get the architecture (first) component of the triple.
raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)
Output Str, turning '\', '', ' ', '"', and anything that doesn't satisfy llvm::isPrint into an escape...
static ErrorSuccess success()
Create a success value.
unit_iterator_range type_units()
Get type units in this context.
uint32_t getLength() const
Returns the length of this table, including the length field, or 0 if the length has not been determi...
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, DILineInfo &Result) const
Fills the Result argument with the file and line information corresponding to Address.
void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection, DWARFSectionKind SectionKind, bool Lazy=false)
Read units from a .debug_info.dwo or .debug_types.dwo section.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
DIInliningInfo getInliningInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
DWARFCompileUnit * CompileUnit
void dump(raw_ostream &OS) const override
static Expected< SymInfo > getSymbolInfo(const object::ObjectFile &Obj, const RelocationRef &Reloc, const LoadedObjectInfo *L, std::map< SymbolRef, SymInfo > &Cache)
Returns the address of symbol relocation used against and a section index.
virtual Triple::ArchType getArch() const =0
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
void dump(raw_ostream &OS, llvm::function_ref< Optional< SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts={}) const
A range adaptor for a pair of iterators.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
This file contains constants used for implementing Dwarf debug support.
Target - Wrapper for Target specific information.
An inferface for inquiring the load address of a loaded object file to be used by the DIContext imple...
void parse(DataExtractor data, unsigned Version)
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
static void dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData, llvm::function_ref< Optional< SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts)
void dump(raw_ostream &OS) const
DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
unit_iterator_range types_section_units()
Get units from .debug_types in this context.
RelocAddrEntry contains relocated value and section index.
void finishedInfoUnits()
Indicate that parsing .debug_info[.dwo] is done, and remaining units will be from ...
const DWARFDebugNames & getDebugNames()
Get a reference to the parsed accelerator table object.
A class that verifies DWARF debug information given a DWARF Context.
virtual section_iterator section_end() const =0
dwarf::Tag getTag() const
LLVM_NODISCARD bool empty() const
const AppleAcceleratorTable & getAppleNames()
Get a reference to the parsed accelerator table object.
Wraps the returned DIEs for a given address.
bool handleAccelTables()
Verify the information in accelerator tables, if they exist.
static ContributionCollection collectContributionData(DWARFContext::unit_iterator_range Units)
unit_iterator_range dwo_units()
Get all units in the DWO context.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
DWARFUnit * getUnitAtIndex(unsigned index)
Get the unit at the specified index.
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, std::array< Optional< uint64_t >, DIDT_ID_Count > DumpOffsets)
Dump a textual representation to OS.
DWARFContext(std::unique_ptr< const DWARFObject > DObj, std::string DWPName="")
bool isLittleEndian() const
const DWARFUnitIndex & getCUIndex()
void dump(raw_ostream &OS) const override
SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...
DINameKind FunctionNameKind
Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr)
Extract an entire table, including all list entries.
bool getFileNameByIndex(uint64_t FileIndex, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const
Extracts filename by its index in filename table in prologue.
Lightweight error class with error context and mandatory checking.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
This class implements an extremely fast bulk output stream that can only output to a stream...
print Print MemDeps of function
StringRef - Represent a constant reference to a string, i.e.
bool hasValidLength() const
Verify that the given length is valid for this table.
void skip(function_ref< void(Error)> ErrorCallback)
Skip the current line table and go to the following line table (if present) immediately.
Helper to allow for parsing of an entire .debug_line section in sequence.
bool done() const
Indicates if the parser has parsed as much as possible.
uint64_t visit(uint32_t Rel, RelocationRef R, uint64_t Value=0)
uint32_t getLineTableOffset() const
const char * getSubroutineName(DINameKind Kind) const
If a DIE represents a subprogram (or inlined subroutine), returns its mangled name (or short name...
void setArch(ArchType Kind)
setArch - Set the architecture (first) component of the triple to a known type.
Optional< uint64_t > toUnsigned(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
uint32_t getOffset() const
Get the offset the parser has reached.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Error extract(const DWARFDataExtractor &data, uint32_t *offset_ptr)
This is a value type class that represents a single section in the list of sections in the object fil...
std::vector< Optional< StrOffsetsContributionDescriptor > > ContributionCollection
Base class for object file relocation visitors.
StringRef extension(StringRef path, Style style=Style::native)
Get extension.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...