1 #ifndef LLVM_DWP_DWP_H
2 #define LLVM_DWP_DWP_H
3 
4 #include "DWPStringPool.h"
5 #include "llvm/ADT/ArrayRef.h"
6 #include "llvm/ADT/MapVector.h"
7 #include "llvm/ADT/StringRef.h"
8 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
9 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
10 #include "llvm/MC/MCSection.h"
11 #include "llvm/MC/MCStreamer.h"
12 #include "llvm/Object/ObjectFile.h"
13 #include "llvm/Support/Error.h"
14 #include <deque>
15 #include <vector>
16 
17 namespace llvm {
18 enum OnCuIndexOverflow {
19   HardStop,
20   SoftStop,
21   Continue,
22 };
23 
24 struct UnitIndexEntry {
25   DWARFUnitIndex::Entry::SectionContribution Contributions[8];
26   std::string Name;
27   std::string DWOName;
28   StringRef DWPName;
29 };
30 
31 // Holds data for Skeleton, Split Compilation, and Type Unit Headers (only in
32 // v5) as defined in Dwarf 5 specification, 7.5.1.2, 7.5.1.3 and Dwarf 4
33 // specification 7.5.1.1.
34 struct InfoSectionUnitHeader {
35   // unit_length field. Note that the type is uint64_t even in 32-bit dwarf.
36   uint64_t Length = 0;
37 
38   // version field.
39   uint16_t Version = 0;
40 
41   // unit_type field. Initialized only if Version >= 5.
42   uint8_t UnitType = 0;
43 
44   // address_size field.
45   uint8_t AddrSize = 0;
46 
47   // debug_abbrev_offset field. Note that the type is uint64_t even in 32-bit
48   // dwarf. It is assumed to be 0.
49   uint64_t DebugAbbrevOffset = 0;
50 
51   // dwo_id field. This resides in the header only if Version >= 5.
52   // In earlier versions, it is read from DW_AT_GNU_dwo_id.
53   std::optional<uint64_t> Signature;
54 
55   // Derived from the length of Length field.
56   dwarf::DwarfFormat Format = dwarf::DwarfFormat::DWARF32;
57 
58   // The size of the Header in bytes. This is derived while parsing the header,
59   // and is stored as a convenience.
60   uint8_t HeaderSize = 0;
61 };
62 
63 struct CompileUnitIdentifiers {
64   uint64_t Signature = 0;
65   const char *Name = "";
66   const char *DWOName = "";
67 };
68 
69 Error write(MCStreamer &Out, ArrayRef<std::string> Inputs,
70             OnCuIndexOverflow OverflowOptValue);
71 
72 unsigned getContributionIndex(DWARFSectionKind Kind, uint32_t IndexVersion);
73 
74 Error handleSection(
75     const StringMap<std::pair<MCSection *, DWARFSectionKind>> &KnownSections,
76     const MCSection *StrSection, const MCSection *StrOffsetSection,
77     const MCSection *TypesSection, const MCSection *CUIndexSection,
78     const MCSection *TUIndexSection, const MCSection *InfoSection,
79     const object::SectionRef &Section, MCStreamer &Out,
80     std::deque<SmallString<32>> &UncompressedSections,
81     uint32_t (&ContributionOffsets)[8], UnitIndexEntry &CurEntry,
82     StringRef &CurStrSection, StringRef &CurStrOffsetSection,
83     std::vector<StringRef> &CurTypesSection,
84     std::vector<StringRef> &CurInfoSection, StringRef &AbbrevSection,
85     StringRef &CurCUIndexSection, StringRef &CurTUIndexSection,
86     std::vector<std::pair<DWARFSectionKind, uint32_t>> &SectionLength);
87 
88 Expected<InfoSectionUnitHeader> parseInfoSectionUnitHeader(StringRef Info);
89 
90 void writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings,
91                             MCSection *StrOffsetSection,
92                             StringRef CurStrSection,
93                             StringRef CurStrOffsetSection, uint16_t Version);
94 
95 Error buildDuplicateError(const std::pair<uint64_t, UnitIndexEntry> &PrevE,
96                           const CompileUnitIdentifiers &ID, StringRef DWPName);
97 
98 void writeIndex(MCStreamer &Out, MCSection *Section,
99                 ArrayRef<unsigned> ContributionOffsets,
100                 const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
101                 uint32_t IndexVersion);
102 
103 } // namespace llvm
104 #endif // LLVM_DWP_DWP_H
105