31 if (DwarfVersion <= 4)
58 if (Form == dwarf::DW_FORM_string)
59 return InfoData.
getCStr(&InfoOffset);
62 case dwarf::DW_FORM_strx1:
63 StrIndex = InfoData.
getU8(&InfoOffset);
65 case dwarf::DW_FORM_strx2:
66 StrIndex = InfoData.
getU16(&InfoOffset);
68 case dwarf::DW_FORM_strx3:
69 StrIndex = InfoData.
getU24(&InfoOffset);
71 case dwarf::DW_FORM_strx4:
72 StrIndex = InfoData.
getU32(&InfoOffset);
74 case dwarf::DW_FORM_strx:
75 case dwarf::DW_FORM_GNU_str_index:
79 return make_error<DWPError>(
80 "string field must be encoded with one of the following: "
81 "DW_FORM_string, DW_FORM_strx, DW_FORM_strx1, DW_FORM_strx2, "
82 "DW_FORM_strx3, DW_FORM_strx4, or DW_FORM_GNU_str_index.");
85 uint64_t StrOffsetsOffset = 4 * StrIndex;
90 return StrData.
getCStr(&StrOffset);
98 if (Header.Version >= 5 && Header.UnitType != dwarf::DW_UT_split_compile)
99 return make_error<DWPError>(
100 std::string(
"unit type DW_UT_split_compile type not found in "
101 "debug_info header. Unexpected unit type 0x" +
102 utostr(Header.UnitType) +
" found"));
110 if (Tag != dwarf::DW_TAG_compile_unit)
111 return make_error<DWPError>(
"top level DIE is not a compile unit");
113 AbbrevData.
getU8(&AbbrevOffset);
119 (
Name != 0 || Form != 0)) {
121 case dwarf::DW_AT_name: {
123 Form, InfoData,
Offset, StrOffsets, Str, Header.Version);
129 case dwarf::DW_AT_GNU_dwo_name:
130 case dwarf::DW_AT_dwo_name: {
132 Form, InfoData,
Offset, StrOffsets, Str, Header.Version);
138 case dwarf::DW_AT_GNU_dwo_id:
147 if (!Header.Signature)
148 return make_error<DWPError>(
"compile unit missing dwo_id");
149 ID.Signature = *Header.Signature;
168 return Index + DW_SECT_INFO;
174 const auto *Off = Entry.getContribution(
Kind);
177 return Section.substr(Off->getOffset(), Off->getLength());
184 bool &AnySectionOverflow) {
187 Twine(
" Section Contribution Offset overflow 4G. Previous Offset ") +
188 Twine(PrevOffset) +
Twine(
", After overflow offset ") +
191 if (OverflowOptValue == OnCuIndexOverflow::Continue) {
194 }
else if (OverflowOptValue == OnCuIndexOverflow::SoftStop) {
195 AnySectionOverflow =
true;
199 return make_error<DWPError>(Msg);
207 bool &AnySectionOverflow) {
210 auto *
I = E.getContributions();
213 auto P = TypeIndexEntries.
insert(std::make_pair(E.getSignature(), TUEntry));
216 auto &Entry =
P.first->second;
218 Entry.Contributions[0] = {};
224 C.setOffset(
C.getOffset() +
I->getOffset());
225 C.setLength(
I->getLength());
228 auto &
C = Entry.Contributions[TypesContributionIndex];
233 C.setOffset(TypesOffset);
235 static_assert(
sizeof(OldOffset) ==
sizeof(TypesOffset));
236 TypesOffset +=
C.getLength();
237 if (OldOffset > TypesOffset) {
239 "Types", OverflowOptValue,
242 if (AnySectionOverflow) {
243 TypesOffset = OldOffset;
253 MCSection *OutputTypes,
const std::vector<StringRef> &TypesSections,
260 while (Data.isValidOffset(
Offset)) {
263 Entry.Contributions[0] = {};
265 C.setOffset(TypesOffset);
268 C.setLength(Data.getU32(&
Offset) + 4);
273 auto Signature = Data.getU64(&
Offset);
274 Offset = PrevOffset +
C.getLength32();
276 auto P = TypeIndexEntries.
insert(std::make_pair(Signature, Entry));
280 Out.
emitBytes(Types.substr(PrevOffset,
C.getLength32()));
282 TypesOffset +=
C.getLength32();
283 if (OldOffset > TypesOffset) {
285 "Types", OverflowOptValue,
288 if (AnySectionOverflow) {
289 TypesOffset = OldOffset;
300 std::string Text =
"\'";
303 bool HasDWO = !DWOName.
empty();
304 bool HasDWP = !DWPName.
empty();
305 if (HasDWO || HasDWP) {
312 if (HasDWO && HasDWP)
314 if (!DWPName.
empty()) {
325 return make_error<DWPError>(
326 (
"failure while decompressing compressed section: '" +
Name +
"', " +
334 auto *Obj = dyn_cast<ELFObjectFileBase>(Sec.
getObject());
338 bool IsLE = isa<object::ELF32LEObjectFile>(Obj) ||
339 isa<object::ELF64LEObjectFile>(Obj);
340 bool Is64 = isa<object::ELF64LEObjectFile>(Obj) ||
341 isa<object::ELF64BEObjectFile>(Obj);
346 UncompressedSections.emplace_back();
347 if (
Error E = Dec->resizeAndDecompress(UncompressedSections.back()))
350 Contents = UncompressedSections.
back();
361 std::tie(Header.Length, Header.Format) =
364 return make_error<DWPError>(
"cannot parse compile unit length: " +
368 return make_error<DWPError>(
369 "compile unit exceeds .debug_info section range: " +
370 utostr(
Offset + Header.Length) +
" >= " + utostr(InfoData.
size()));
375 return make_error<DWPError>(
"cannot parse compile unit version: " +
379 if (Header.Version >= 5) {
382 MinHeaderLength = 16;
387 if (Header.Length < MinHeaderLength) {
388 return make_error<DWPError>(
"unit length is too small: expected at least " +
389 utostr(MinHeaderLength) +
" got " +
390 utostr(Header.Length) +
".");
392 if (Header.Version >= 5) {
397 if (Header.UnitType == dwarf::DW_UT_split_type) {
399 MinHeaderLength += 4;
400 if (Header.Length < MinHeaderLength)
401 return make_error<DWPError>(
"type unit is missing type offset");
411 Header.HeaderSize =
Offset;
421 auto NewOffset = OffsetRemapping[OldOffset];
432 if (CurStrSection.
empty() || CurStrOffsetSection.
empty())
440 while (
const char *S =
Data.getCStr(&LocalOffset)) {
441 OffsetRemapping[PrevOffset] =
442 Strings.getOffset(S, LocalOffset - PrevOffset);
443 PrevOffset = LocalOffset;
456 "StrOffsetSection size is less than its header");
461 if (HeaderSize == 8) {
462 ContributionSize =
Data.getU32(&HeaderLengthOffset);
463 }
else if (HeaderSize == 16) {
464 HeaderLengthOffset += 4;
465 ContributionSize =
Data.getU64(&HeaderLengthOffset);
467 ContributionEnd = ContributionSize + HeaderLengthOffset;
481 for (
const auto &E : IndexEntries)
482 for (
size_t I = 0;
I != std::size(E.second.Contributions); ++
I)
483 if (ContributionOffsets[
I])
485 ? E.second.Contributions[
I].getOffset32()
486 : E.second.Contributions[
I].getLength32()),
494 if (IndexEntries.
empty())
497 unsigned Columns = 0;
498 for (
auto &
C : ContributionOffsets)
505 for (
const auto &
P : IndexEntries) {
508 auto HP = ((S >> 32) & Mask) | 1;
510 assert(S != IndexEntries.
begin()[Buckets[
H] - 1].first &&
525 for (
const auto &
I : Buckets)
529 for (
const auto &
I : Buckets)
533 for (
size_t I = 0;
I != ContributionOffsets.
size(); ++
I)
534 if (ContributionOffsets[
I])
546 return make_error<DWPError>(
547 std::string(
"duplicate DWO ID (") + utohexstr(PrevE.first) +
") in " +
549 PrevE.second.DWOName) +
554 const StringMap<std::pair<MCSection *, DWARFSectionKind>> &KnownSections,
562 std::vector<StringRef> &CurTypesSection,
563 std::vector<StringRef> &CurInfoSection,
StringRef &AbbrevSection,
565 std::vector<std::pair<DWARFSectionKind, uint32_t>> &SectionLength) {
569 if (Section.isVirtual())
588 auto SectionPair = KnownSections.find(
Name);
589 if (SectionPair == KnownSections.end())
594 SectionLength.push_back(std::make_pair(
Kind, Contents.
size()));
597 if (
Kind == DW_SECT_ABBREV) {
598 AbbrevSection = Contents;
602 MCSection *OutSection = SectionPair->second.first;
603 if (OutSection == StrOffsetSection)
604 CurStrOffsetSection = Contents;
605 else if (OutSection == StrSection)
606 CurStrSection = Contents;
607 else if (OutSection == TypesSection)
608 CurTypesSection.push_back(Contents);
609 else if (OutSection == CUIndexSection)
610 CurCUIndexSection = Contents;
611 else if (OutSection == TUIndexSection)
612 CurTUIndexSection = Contents;
613 else if (OutSection == InfoSection)
614 CurInfoSection.push_back(Contents);
625 MCSection *
const StrSection = MCOFI.getDwarfStrDWOSection();
626 MCSection *
const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
627 MCSection *
const TypesSection = MCOFI.getDwarfTypesDWOSection();
628 MCSection *
const CUIndexSection = MCOFI.getDwarfCUIndexSection();
629 MCSection *
const TUIndexSection = MCOFI.getDwarfTUIndexSection();
630 MCSection *
const InfoSection = MCOFI.getDwarfInfoDWOSection();
632 {
"debug_info.dwo", {InfoSection, DW_SECT_INFO}},
634 {
"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
637 {
"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}},
638 {
"debug_macro.dwo", {MCOFI.getDwarfMacroDWOSection(), DW_SECT_MACRO}},
639 {
"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}},
640 {
"debug_loclists.dwo",
641 {MCOFI.getDwarfLoclistsDWOSection(), DW_SECT_LOCLISTS}},
642 {
"debug_rnglists.dwo",
643 {MCOFI.getDwarfRnglistsDWOSection(), DW_SECT_RNGLISTS}},
650 uint32_t ContributionOffsets[8] = {};
653 bool AnySectionOverflow =
false;
660 std::deque<SmallString<32>> UncompressedSections;
662 for (
const auto &Input : Inputs) {
666 [&](std::unique_ptr<ECError> EC) ->
Error {
667 return createFileError(Input, Error(std::move(EC)));
671 auto &Obj = *ErrOrObj->getBinary();
678 std::vector<StringRef> CurTypesSection;
679 std::vector<StringRef> CurInfoSection;
687 std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLength;
689 for (
const auto &Section : Obj.sections())
691 KnownSections, StrSection, StrOffsetSection, TypesSection,
692 CUIndexSection, TUIndexSection, InfoSection, Section, Out,
693 UncompressedSections, ContributionOffsets, CurEntry,
694 CurStrSection, CurStrOffsetSection, CurTypesSection,
695 CurInfoSection, AbbrevSection, CurCUIndexSection,
696 CurTUIndexSection, SectionLength))
699 if (CurInfoSection.empty())
710 IndexVersion =
Version < 5 ? 2 : 5;
711 }
else if (
Version != Header.Version) {
712 return make_error<DWPError>(
"incompatible DWARF compile unit versions.");
716 CurStrOffsetSection, Header.Version);
718 for (
auto Pair : SectionLength) {
722 uint32_t OldOffset = ContributionOffsets[Index];
724 if (OldOffset > ContributionOffsets[Index]) {
726 for (
auto &Section : Obj.sections()) {
727 if (SectionIndex == Index) {
729 OldOffset, ContributionOffsets[Index], *Section.getName(),
730 OverflowOptValue, AnySectionOverflow))
735 if (AnySectionOverflow)
742 if (CurCUIndexSection.
empty()) {
743 bool FoundCUUnit =
false;
747 while (
Info.size() > UnitOffset) {
757 C.setOffset(InfoSectionOffset);
758 C.setLength(Header.Length + 4);
760 if (std::numeric_limits<uint32_t>::max() - InfoSectionOffset <
763 InfoSectionOffset, InfoSectionOffset +
C.getLength32(),
764 "debug_info", OverflowOptValue, AnySectionOverflow))
766 if (AnySectionOverflow) {
767 if (Header.Version < 5 ||
768 Header.UnitType == dwarf::DW_UT_split_compile)
774 UnitOffset +=
C.getLength32();
775 if (Header.Version < 5 ||
776 Header.UnitType == dwarf::DW_UT_split_compile) {
778 Header, AbbrevSection,
779 Info.substr(UnitOffset -
C.getLength32(),
C.getLength32()),
780 CurStrOffsetSection, CurStrSection);
784 const auto &
ID = *EID;
785 auto P = IndexEntries.
insert(std::make_pair(
ID.Signature, Entry));
788 P.first->second.Name =
ID.Name;
789 P.first->second.DWOName =
ID.DWOName;
792 }
else if (Header.UnitType == dwarf::DW_UT_split_type) {
793 auto P = TypeIndexEntries.
insert(
794 std::make_pair(*Header.Signature, Entry));
799 Info.substr(UnitOffset -
C.getLength32(),
C.getLength32()));
800 InfoSectionOffset +=
C.getLength32();
802 if (AnySectionOverflow)
807 return make_error<DWPError>(
"no compile unit found in file: " + Input);
809 if (IndexVersion == 2) {
812 Out, TypeIndexEntries, TypesSection, CurTypesSection, CurEntry,
814 OverflowOptValue, AnySectionOverflow))
817 if (AnySectionOverflow)
822 if (CurInfoSection.size() != 1)
823 return make_error<DWPError>(
"expected exactly one occurrence of a debug "
824 "info section in a .dwp file");
828 DataExtractor CUIndexData(CurCUIndexSection, Obj.isLittleEndian(), 0);
829 if (!CUIndex.
parse(CUIndexData))
830 return make_error<DWPError>(
"failed to parse cu_index");
832 return make_error<DWPError>(
"incompatible cu_index versions, found " +
834 " and expecting " + utostr(IndexVersion));
838 auto *
I = E.getContributions();
841 auto P = IndexEntries.
insert(std::make_pair(E.getSignature(), CurEntry));
857 const auto &
ID = *EID;
860 auto &NewEntry =
P.first->second;
861 NewEntry.Name =
ID.Name;
862 NewEntry.DWOName =
ID.DWOName;
863 NewEntry.DWPName = Input;
869 C.setOffset(
C.getOffset() +
I->getOffset());
870 C.setLength(
I->getLength());
874 auto &
C = NewEntry.Contributions[Index];
876 C.setOffset(InfoSectionOffset);
877 InfoSectionOffset +=
C.getLength32();
880 if (!CurTUIndexSection.
empty()) {
886 TUSectionKind = DW_SECT_INFO;
887 OutSection = InfoSection;
888 TypeInputSection = DwpSingleInfoSection;
891 if (CurTypesSection.size() != 1)
892 return make_error<DWPError>(
893 "multiple type unit sections in .dwp file");
896 OutSection = TypesSection;
897 TypeInputSection = CurTypesSection.
front();
901 DataExtractor TUIndexData(CurTUIndexSection, Obj.isLittleEndian(), 0);
902 if (!TUIndex.
parse(TUIndexData))
903 return make_error<DWPError>(
"failed to parse tu_index");
905 return make_error<DWPError>(
"incompatible tu_index versions, found " +
907 " and expecting " + utostr(IndexVersion));
909 unsigned TypesContributionIndex =
912 Out, TypeIndexEntries, TUIndex, OutSection, TypeInputSection,
913 CurEntry, ContributionOffsets[TypesContributionIndex],
914 TypesContributionIndex, OverflowOptValue, AnySectionOverflow))
917 if (AnySectionOverflow)
925 ContributionOffsets[0] = 0;
927 writeIndex(Out, MCOFI.getDwarfTUIndexSection(), ContributionOffsets,
928 TypeIndexEntries, IndexVersion);
935 ContributionOffsets[0] = 1;
938 writeIndex(Out, MCOFI.getDwarfCUIndexSection(), ContributionOffsets,
939 IndexEntries, IndexVersion);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Analysis containing CSE Info
static unsigned getContributionIndex(DWARFSectionKind Kind, uint32_t IndexVersion)
static uint64_t getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode)
static Error handleCompressedSection(std::deque< SmallString< 32 > > &UncompressedSections, SectionRef Sec, StringRef Name, StringRef &Contents)
static std::string buildDWODescription(StringRef Name, StringRef DWPName, StringRef DWOName)
static uint64_t debugStrOffsetsHeaderSize(DataExtractor StrOffsetsData, uint16_t DwarfVersion)
static Expected< const char * > getIndexedString(dwarf::Form Form, DataExtractor InfoData, uint64_t &InfoOffset, StringRef StrOffsets, StringRef Str, uint16_t Version)
static Error addAllTypesFromTypesSection(MCStreamer &Out, MapVector< uint64_t, UnitIndexEntry > &TypeIndexEntries, MCSection *OutputTypes, const std::vector< StringRef > &TypesSections, const UnitIndexEntry &CUEntry, uint32_t &TypesOffset, OnCuIndexOverflow OverflowOptValue, bool &AnySectionOverflow)
static unsigned getOnDiskSectionId(unsigned Index)
static Expected< CompileUnitIdentifiers > getCUIdentifiers(InfoSectionUnitHeader &Header, StringRef Abbrev, StringRef Info, StringRef StrOffsets, StringRef Str)
static Error sectionOverflowErrorOrWarning(uint32_t PrevOffset, uint32_t OverflowedOffset, StringRef SectionName, OnCuIndexOverflow OverflowOptValue, bool &AnySectionOverflow)
static mc::RegisterMCTargetOptionsFlags MCTargetOptionsFlags
static StringRef getSubsection(StringRef Section, const DWARFUnitIndex::Entry &Entry, DWARFSectionKind Kind)
static Error createError(StringRef Name, Error E)
static bool isSupportedSectionKind(DWARFSectionKind Kind)
static Error addAllTypesFromDWP(MCStreamer &Out, MapVector< uint64_t, UnitIndexEntry > &TypeIndexEntries, const DWARFUnitIndex &TUIndex, MCSection *OutputTypes, StringRef Types, const UnitIndexEntry &TUEntry, uint32_t &TypesOffset, unsigned TypesContributionIndex, OnCuIndexOverflow OverflowOptValue, bool &AnySectionOverflow)
static uint32_t getFlags(const Symbol *Sym)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
void setOffset(uint64_t Value)
void setLength(uint64_t Value)
uint32_t getLength32() const
uint64_t getOffset() const
uint32_t getVersion() const
LLVM_ABI bool parse(DataExtractor IndexData)
ArrayRef< DWARFSectionKind > getColumnKinds() const
ArrayRef< Entry > getRows() const
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.
const MCObjectFileInfo * getObjectFileInfo() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Streaming machine code generation interface.
MCContext & getContext() const
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
This class implements a map that also provides access to all stored values in a deterministic order.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
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.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
char back() const
back - Get the last character in the string.
constexpr size_t size() const
size - Get the string size.
char front() const
front - Get the first character in the string.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static LLVM_ABI void defaultWarningHandler(Error Warning)
Implement default handling for Warning.
static LLVM_ABI Expected< Decompressor > create(StringRef Name, StringRef Data, bool IsLE, bool Is64Bit)
Create decompressor object.
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
This is a value type class that represents a single section in the list of sections in the object fil...
const ObjectFile * getObject() const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
This is an optimization pass for GlobalISel generic memory operations.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
LLVM_ABI Error buildDuplicateError(const std::pair< uint64_t, UnitIndexEntry > &PrevE, const CompileUnitIdentifiers &ID, StringRef DWPName)
LLVM_ABI void writeIndex(MCStreamer &Out, MCSection *Section, ArrayRef< unsigned > ContributionOffsets, const MapVector< uint64_t, UnitIndexEntry > &IndexEntries, uint32_t IndexVersion)
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
static void writeNewOffsetsTo(MCStreamer &Out, DataExtractor &Data, DenseMap< uint64_t, uint32_t > &OffsetRemapping, uint64_t &Offset, uint64_t &Size)
LLVM_ABI void writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings, MCSection *StrOffsetSection, StringRef CurStrSection, StringRef CurStrOffsetSection, uint16_t Version)
DWARFSectionKind
The enum of section identifiers to be used in internal interfaces.
@ DW_SECT_EXT_unknown
Denotes a value read from an index section that does not correspond to any of the supported standards...
LLVM_ABI uint32_t serializeSectionKind(DWARFSectionKind Kind, unsigned IndexVersion)
Convert the internal value for a section kind to an on-disk value.
LLVM_ABI Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
LLVM_ABI Error handleSection(const StringMap< std::pair< MCSection *, DWARFSectionKind > > &KnownSections, const MCSection *StrSection, const MCSection *StrOffsetSection, const MCSection *TypesSection, const MCSection *CUIndexSection, const MCSection *TUIndexSection, const MCSection *InfoSection, const object::SectionRef &Section, MCStreamer &Out, std::deque< SmallString< 32 > > &UncompressedSections, uint32_t(&ContributionOffsets)[8], UnitIndexEntry &CurEntry, StringRef &CurStrSection, StringRef &CurStrOffsetSection, std::vector< StringRef > &CurTypesSection, std::vector< StringRef > &CurInfoSection, StringRef &AbbrevSection, StringRef &CurCUIndexSection, StringRef &CurTUIndexSection, std::vector< std::pair< DWARFSectionKind, uint32_t > > &SectionLength)
void writeIndexTable(MCStreamer &Out, ArrayRef< unsigned > ContributionOffsets, const MapVector< uint64_t, UnitIndexEntry > &IndexEntries, const AccessField &Field)
LLVM_ABI Expected< InfoSectionUnitHeader > parseInfoSectionUnitHeader(StringRef Info)
const char * toString(DWARFSectionKind Kind)
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
DWARFUnitIndex::Entry::SectionContribution Contributions[8]
Create this object with static storage to register mc-related command line options.