llvm.org GIT mirror llvm / fd770ea
[DWARF] NFC: Collect info used by DWARFFormValue into a helper. Some forms have sizes that depend on the DWARF version, DWARF format (32/64-bit), or the size of an address. Collect these into a struct to simplify passing them around. Require callers to provide one when they query a form's size. Differential Revision: http://reviews.llvm.org/D34570 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306315 91177308-0d34-0410-b5e6-96231b3b80d8 Paul Robinson 2 years ago
11 changed file(s) with 223 addition(s) and 270 deletion(s). Raw diff Collapse all Expand all
1111
1212 #include "llvm/ADT/StringRef.h"
1313 #include "llvm/DebugInfo/DIContext.h"
14 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
1415 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
1516 #include "llvm/Support/DataExtractor.h"
1617 #include
4243 /// The size in bytes of the statement information for this compilation unit
4344 /// (not including the total_length field itself).
4445 uint64_t TotalLength;
45 /// Version identifier for the statement information format.
46 uint16_t Version;
47 /// In v5, size in bytes of an address (or segment offset).
48 uint8_t AddressSize;
46 /// Version, address size (starting in v5), and DWARF32/64 format; these
47 /// parameters affect interpretation of forms (used in the directory and
48 /// file tables starting with v5).
49 DWARFFormParams FormParams;
4950 /// In v5, size in bytes of a segment selector.
5051 uint8_t SegSelectorSize;
5152 /// The number of bytes following the prologue_length field to the beginning
7071 std::vector IncludeDirectories;
7172 std::vector FileNames;
7273
73 bool IsDWARF64;
74
75 uint32_t sizeofTotalLength() const { return IsDWARF64 ? 12 : 4; }
76
77 uint32_t sizeofPrologueLength() const { return IsDWARF64 ? 8 : 4; }
74 const DWARFFormParams getFormParams() const { return FormParams; }
75 uint16_t getVersion() const { return FormParams.Version; }
76 uint8_t getAddressSize() const { return FormParams.AddrSize; }
77 bool isDWARF64() const { return FormParams.Format == dwarf::DWARF64; }
78
79 uint32_t sizeofTotalLength() const { return isDWARF64() ? 12 : 4; }
80
81 uint32_t sizeofPrologueLength() const { return isDWARF64() ? 8 : 4; }
7882
7983 /// Length of the prologue in bytes.
8084 uint32_t getLength() const {
81 return PrologueLength + sizeofTotalLength() + sizeof(Version) +
85 return PrologueLength + sizeofTotalLength() + sizeof(getVersion()) +
8286 sizeofPrologueLength();
8387 }
8488
2020
2121 class DWARFUnit;
2222 class raw_ostream;
23
24 /// A helper struct for DWARFFormValue methods, providing information that
25 /// allows it to know the byte size of DW_FORM values that vary in size
26 /// depending on the DWARF version, address byte size, or DWARF32/DWARF64.
27 struct DWARFFormParams {
28 uint16_t Version;
29 uint8_t AddrSize;
30 dwarf::DwarfFormat Format;
31
32 /// The definition of the size of form DW_FORM_ref_addr depends on the
33 /// version. In DWARF v2 it's the size of an address; after that, it's the
34 /// size of a reference.
35 uint8_t getRefAddrByteSize() const {
36 if (Version == 2)
37 return AddrSize;
38 return getDwarfOffsetByteSize();
39 }
40
41 /// The size of a reference is determined by the DWARF 32/64-bit format.
42 uint8_t getDwarfOffsetByteSize() const {
43 switch (Format) {
44 case dwarf::DwarfFormat::DWARF32:
45 return 4;
46 case dwarf::DwarfFormat::DWARF64:
47 return 8;
48 }
49 llvm_unreachable("Invalid Format value");
50 }
51 };
2352
2453 class DWARFFormValue {
2554 public:
103132
104133 /// Get the fixed byte size for a given form.
105134 ///
106 /// If the form always has a fixed valid byte size that doesn't depend on a
107 /// DWARFUnit, then an Optional with a value will be returned. If the form
108 /// can vary in size depending on the DWARFUnit (DWARF version, address byte
109 /// size, or DWARF 32/64) and the DWARFUnit is valid, then an Optional with a
110 /// valid value is returned. If the form is always encoded using a variable
111 /// length storage format (ULEB or SLEB numbers or blocks) or the size
112 /// depends on a DWARFUnit and the DWARFUnit is NULL, then None will be
113 /// returned.
114 /// \param Form The DWARF form to get the fixed byte size for
115 /// \param U The DWARFUnit that can be used to help determine the byte size.
116 ///
117 /// \returns Optional value with the fixed byte size or None if
118 /// \p Form doesn't have a fixed byte size or a DWARFUnit wasn't supplied
119 /// and was needed to calculate the byte size.
120 static Optional getFixedByteSize(dwarf::Form Form,
121 const DWARFUnit *U = nullptr);
122
123 /// Get the fixed byte size for a given form.
124 ///
125 /// If the form has a fixed byte size given a valid DWARF version and address
126 /// byte size, then an Optional with a valid value is returned. If the form
127 /// is always encoded using a variable length storage format (ULEB or SLEB
128 /// numbers or blocks) then None will be returned.
129 ///
130 /// \param Form DWARF form to get the fixed byte size for
131 /// \param Version DWARF version number.
132 /// \param AddrSize size of an address in bytes.
133 /// \param Format enum value from llvm::dwarf::DwarfFormat.
135 /// If the form has a fixed byte size, then an Optional with a value will be
136 /// returned. If the form is always encoded using a variable length storage
137 /// format (ULEB or SLEB numbers or blocks) then None will be returned.
138 ///
139 /// \param Form DWARF form to get the fixed byte size for.
140 /// \param FormParams DWARF parameters to help interpret forms.
134141 /// \returns Optional value with the fixed byte size or None if
135142 /// \p Form doesn't have a fixed byte size.
136 static Optional getFixedByteSize(dwarf::Form Form, uint16_t Version,
137 uint8_t AddrSize,
138 llvm::dwarf::DwarfFormat Format);
139
140 /// Skip a form in \p DebugInfoData at offset specified by \p OffsetPtr.
141 ///
142 /// Skips the bytes for this form in the debug info and updates the offset.
143 ///
144 /// \param DebugInfoData the .debug_info data to use to skip the value.
145 /// \param OffsetPtr a reference to the offset that will be updated.
146 /// \param U the DWARFUnit to use when skipping the form in case the form
147 /// size differs according to data in the DWARFUnit.
143 static Optional getFixedByteSize(dwarf::Form Form,
144 const DWARFFormParams &FormParams);
145
146 /// Skip a form's value in \p DebugInfoData at the offset specified by
147 /// \p OffsetPtr.
148 ///
149 /// Skips the bytes for the current form and updates the offset.
150 ///
151 /// \param DebugInfoData The data where we want to skip the value.
152 /// \param OffsetPtr A reference to the offset that will be updated.
153 /// \param Params DWARF parameters to help interpret forms.
148154 /// \returns true on success, false if the form was not skipped.
149155 bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr,
150 const DWARFUnit *U) const;
151
152 /// Skip a form in \p DebugInfoData at offset specified by \p OffsetPtr.
153 ///
154 /// Skips the bytes for this form in the debug info and updates the offset.
155 ///
156 /// \param Form the DW_FORM enumeration that indicates the form to skip.
157 /// \param DebugInfoData the .debug_info data to use to skip the value.
158 /// \param OffsetPtr a reference to the offset that will be updated.
159 /// \param U the DWARFUnit to use when skipping the form in case the form
160 /// size differs according to data in the DWARFUnit.
156 const DWARFFormParams &Params) const {
157 return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params);
158 }
159
160 /// Skip a form's value in \p DebugInfoData at the offset specified by
161 /// \p OffsetPtr.
162 ///
163 /// Skips the bytes for the specified form and updates the offset.
164 ///
165 /// \param Form The DW_FORM enumeration that indicates the form to skip.
166 /// \param DebugInfoData The data where we want to skip the value.
167 /// \param OffsetPtr A reference to the offset that will be updated.
168 /// \param FormParams DWARF parameters to help interpret forms.
161169 /// \returns true on success, false if the form was not skipped.
162170 static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
163 uint32_t *OffsetPtr, const DWARFUnit *U);
164
165 /// Skip a form in \p DebugInfoData at offset specified by \p OffsetPtr.
166 ///
167 /// Skips the bytes for this form in the debug info and updates the offset.
168 ///
169 /// \param Form the DW_FORM enumeration that indicates the form to skip.
170 /// \param DebugInfoData the .debug_info data to use to skip the value.
171 /// \param OffsetPtr a reference to the offset that will be updated.
172 /// \param Version DWARF version number.
173 /// \param AddrSize size of an address in bytes.
174 /// \param Format enum value from llvm::dwarf::DwarfFormat.
175 /// \returns true on success, false if the form was not skipped.
176 static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
177 uint32_t *OffsetPtr, uint16_t Version, uint8_t AddrSize,
178 llvm::dwarf::DwarfFormat Format);
171 uint32_t *OffsetPtr, const DWARFFormParams &FormParams);
179172
180173 private:
181174 void dumpString(raw_ostream &OS) const;
1818 #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
1919 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
2020 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
21 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
2122 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
2223 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
2324 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
126127 bool isDWO;
127128 const DWARFUnitSectionBase &UnitSection;
128129
130 // Version, address size, and DWARF format.
131 DWARFFormParams FormParams;
132
129133 uint32_t Offset;
130134 uint32_t Length;
131135 const DWARFAbbreviationDeclarationSet *Abbrevs;
132 uint16_t Version;
133136 uint8_t UnitType;
134 uint8_t AddrSize;
135137 uint64_t BaseAddr;
136138 /// The compile unit debug information entry items.
137139 std::vector DieArray;
158160 virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr);
159161
160162 /// Size in bytes of the unit header.
161 virtual uint32_t getHeaderSize() const { return Version <= 4 ? 11 : 12; }
163 virtual uint32_t getHeaderSize() const { return getVersion() <= 4 ? 11 : 12; }
162164
163165 public:
164166 DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
196198 uint64_t getStringOffsetSectionRelocation(uint32_t Index) const;
197199
198200 DataExtractor getDebugInfoExtractor() const {
199 return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize);
201 return DataExtractor(InfoSection.Data, isLittleEndian,
202 getAddressByteSize());
200203 }
201204
202205 DataExtractor getStringExtractor() const {
219222 uint32_t getOffset() const { return Offset; }
220223 uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
221224 uint32_t getLength() const { return Length; }
222 uint16_t getVersion() const { return Version; }
223
224 dwarf::DwarfFormat getFormat() const {
225 return dwarf::DwarfFormat::DWARF32; // FIXME: Support DWARF64.
225
226 const DWARFFormParams &getFormParams() const { return FormParams; }
227 uint16_t getVersion() const { return FormParams.Version; }
228 dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
229 uint8_t getAddressByteSize() const { return FormParams.AddrSize; }
230 uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); }
231 uint8_t getDwarfOffsetByteSize() const {
232 return FormParams.getDwarfOffsetByteSize();
226233 }
227234
228235 const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
230237 }
231238
232239 uint8_t getUnitType() const { return UnitType; }
233 uint8_t getAddressByteSize() const { return AddrSize; }
234
235 uint8_t getRefAddrByteSize() const {
236 if (Version == 2)
237 return AddrSize;
238 return getDwarfOffsetByteSize();
239 }
240
241 uint8_t getDwarfOffsetByteSize() const {
242 if (getFormat() == dwarf::DwarfFormat::DWARF64)
243 return 8;
244 return 4;
245 }
246240
247241 uint64_t getBaseAddress() const { return BaseAddr; }
248242
6464 if (A && F) {
6565 Optional V;
6666 bool IsImplicitConst = (F == DW_FORM_implicit_const);
67 if (IsImplicitConst)
67 if (IsImplicitConst) {
6868 V = Data.getSLEB128(OffsetPtr);
69 else if (auto Size = DWARFFormValue::getFixedByteSize(F))
70 V = *Size;
71 AttributeSpecs.push_back(AttributeSpec(A, F, V));
72 if (IsImplicitConst)
69 AttributeSpecs.push_back(AttributeSpec(A, F, V));
7370 continue;
71 }
7472 // If this abbrevation still has a fixed byte size, then update the
7573 // FixedAttributeSize as needed.
76 if (FixedAttributeSize) {
77 if (V)
78 FixedAttributeSize->NumBytes += *V;
79 else {
80 switch (F) {
81 case DW_FORM_addr:
82 ++FixedAttributeSize->NumAddrs;
83 break;
84
85 case DW_FORM_ref_addr:
86 ++FixedAttributeSize->NumRefAddrs;
87 break;
88
89 case DW_FORM_strp:
90 case DW_FORM_GNU_ref_alt:
91 case DW_FORM_GNU_strp_alt:
92 case DW_FORM_line_strp:
93 case DW_FORM_sec_offset:
94 case DW_FORM_strp_sup:
95 ++FixedAttributeSize->NumDwarfOffsets;
96 break;
97
98 default:
99 // Indicate we no longer have a fixed byte size for this
100 // abbreviation by clearing the FixedAttributeSize optional value
101 // so it doesn't have a value.
102 FixedAttributeSize.reset();
103 break;
104 }
74 switch (F) {
75 case DW_FORM_addr:
76 if (FixedAttributeSize)
77 ++FixedAttributeSize->NumAddrs;
78 break;
79
80 case DW_FORM_ref_addr:
81 if (FixedAttributeSize)
82 ++FixedAttributeSize->NumRefAddrs;
83 break;
84
85 case DW_FORM_strp:
86 case DW_FORM_GNU_ref_alt:
87 case DW_FORM_GNU_strp_alt:
88 case DW_FORM_line_strp:
89 case DW_FORM_sec_offset:
90 case DW_FORM_strp_sup:
91 if (FixedAttributeSize)
92 ++FixedAttributeSize->NumDwarfOffsets;
93 break;
94
95 default:
96 // The form has a byte size that doesn't depend on Params.
97 // If it's a fixed size, keep track of it.
98 if (auto Size =
99 DWARFFormValue::getFixedByteSize(F, DWARFFormParams())) {
100 V = *Size;
101 if (FixedAttributeSize)
102 FixedAttributeSize->NumBytes += *V;
103 break;
105104 }
105 // Indicate we no longer have a fixed byte size for this
106 // abbreviation by clearing the FixedAttributeSize optional value
107 // so it doesn't have a value.
108 FixedAttributeSize.reset();
109 break;
106110 }
111 // Record this attribute and its fixed size if it has one.
112 AttributeSpecs.push_back(AttributeSpec(A, F, V));
107113 } else if (A == 0 && F == 0) {
108114 // We successfully reached the end of this abbreviation declaration
109115 // since both attribute and form are zero.
185191 if (auto FixedSize = Spec.getByteSize(U))
186192 Offset += *FixedSize;
187193 else
188 DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset, &U);
194 DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset,
195 U.getFormParams());
189196 ++AttrIndex;
190197 }
191198 return None;
210217 if (ByteSizeOrValue)
211218 return ByteSizeOrValue;
212219 Optional S;
213 auto FixedByteSize = DWARFFormValue::getFixedByteSize(Form, &U);
220 auto FixedByteSize =
221 DWARFFormValue::getFixedByteSize(Form, U.getFormParams());
214222 if (FixedByteSize)
215223 S = *FixedByteSize;
216224 return S;
5858 // Attribute byte size if fixed, just add the size to the offset.
5959 *OffsetPtr += *FixedSize;
6060 } else if (!DWARFFormValue::skipValue(AttrSpec.Form, DebugInfoData,
61 OffsetPtr, &U)) {
61 OffsetPtr, U.getFormParams())) {
6262 // We failed to skip this attribute's value, restore the original offset
6363 // and return the failure status.
6464 *OffsetPtr = Offset;
4343 DWARFDebugLine::Prologue::Prologue() { clear(); }
4444
4545 void DWARFDebugLine::Prologue::clear() {
46 TotalLength = Version = PrologueLength = 0;
47 AddressSize = SegSelectorSize = 0;
46 TotalLength = PrologueLength = 0;
47 SegSelectorSize = 0;
4848 MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
4949 OpcodeBase = 0;
50 IsDWARF64 = false;
50 FormParams = DWARFFormParams({0, 0, DWARF32});
5151 StandardOpcodeLengths.clear();
5252 IncludeDirectories.clear();
5353 FileNames.clear();
5656 void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const {
5757 OS << "Line table prologue:\n"
5858 << format(" total_length: 0x%8.8" PRIx64 "\n", TotalLength)
59 << format(" version: %u\n", Version)
60 << format(Version >= 5 ? " address_size: %u\n" : "", AddressSize)
61 << format(Version >= 5 ? " seg_select_size: %u\n" : "", SegSelectorSize)
62 << format(" prologue_length: 0x%8.8" PRIx64 "\n", PrologueLength)
59 << format(" version: %u\n", getVersion());
60 if (getVersion() >= 5)
61 OS << format(" address_size: %u\n", getAddressSize())
62 << format(" seg_select_size: %u\n", SegSelectorSize);
63 OS << format(" prologue_length: 0x%8.8" PRIx64 "\n", PrologueLength)
6364 << format(" min_inst_length: %u\n", MinInstLength)
64 << format(Version >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst)
65 << format(getVersion() >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst)
6566 << format(" default_is_stmt: %u\n", DefaultIsStmt)
6667 << format(" line_base: %i\n", LineBase)
6768 << format(" line_range: %u\n", LineRange)
142143 static bool
143144 parseV5DirFileTables(DataExtractor DebugLineData, uint32_t *OffsetPtr,
144145 uint64_t EndPrologueOffset,
146 const DWARFFormParams &FormParams,
145147 std::vector &IncludeDirectories,
146148 std::vector &FileNames) {
147149 // Get the directory entry description.
164166 IncludeDirectories.push_back(Value.getAsCString().getValue());
165167 break;
166168 default:
167 if (!Value.skipValue(DebugLineData, OffsetPtr, nullptr))
169 if (!Value.skipValue(DebugLineData, OffsetPtr, FormParams))
168170 return false;
169171 }
170172 }
216218 clear();
217219 TotalLength = DebugLineData.getU32(OffsetPtr);
218220 if (TotalLength == UINT32_MAX) {
219 IsDWARF64 = true;
221 FormParams.Format = dwarf::DWARF64;
220222 TotalLength = DebugLineData.getU64(OffsetPtr);
221 } else if (TotalLength > 0xffffff00) {
222 return false;
223 }
224 Version = DebugLineData.getU16(OffsetPtr);
225 if (Version < 2)
226 return false;
227
228 if (Version >= 5) {
229 AddressSize = DebugLineData.getU8(OffsetPtr);
223 } else if (TotalLength >= 0xffffff00) {
224 return false;
225 }
226 FormParams.Version = DebugLineData.getU16(OffsetPtr);
227 if (getVersion() < 2)
228 return false;
229
230 if (getVersion() >= 5) {
231 FormParams.AddrSize = DebugLineData.getU8(OffsetPtr);
232 assert(getAddressSize() == DebugLineData.getAddressSize() &&
233 "Line table header and data extractor disagree");
230234 SegSelectorSize = DebugLineData.getU8(OffsetPtr);
231235 }
232236
233237 PrologueLength = DebugLineData.getUnsigned(OffsetPtr, sizeofPrologueLength());
234238 const uint64_t EndPrologueOffset = PrologueLength + *OffsetPtr;
235239 MinInstLength = DebugLineData.getU8(OffsetPtr);
236 if (Version >= 4)
240 if (getVersion() >= 4)
237241 MaxOpsPerInst = DebugLineData.getU8(OffsetPtr);
238242 DefaultIsStmt = DebugLineData.getU8(OffsetPtr);
239243 LineBase = DebugLineData.getU8(OffsetPtr);
246250 StandardOpcodeLengths.push_back(OpLen);
247251 }
248252
249 if (Version >= 5) {
253 if (getVersion() >= 5) {
250254 if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
251 IncludeDirectories, FileNames)) {
255 getFormParams(), IncludeDirectories, FileNames)) {
252256 fprintf(stderr,
253257 "warning: parsing line table prologue at 0x%8.8" PRIx64
254258 " found an invalid directory or file table description at"
5858 DWARFFormValue::FC_Flag, // 0x19 DW_FORM_flag_present
5959 };
6060
61 namespace {
62
63 /// A helper class that can be used in DWARFFormValue.cpp functions that need
64 /// to know the byte size of DW_FORM values that vary in size depending on the
65 /// DWARF version, address byte size, or DWARF32 or DWARF64.
66 class FormSizeHelper {
67 uint16_t Version;
68 uint8_t AddrSize;
69 llvm::dwarf::DwarfFormat Format;
70
71 public:
72 FormSizeHelper(uint16_t V, uint8_t A, llvm::dwarf::DwarfFormat F)
73 : Version(V), AddrSize(A), Format(F) {}
74
75 uint8_t getAddressByteSize() const { return AddrSize; }
76
77 uint8_t getRefAddrByteSize() const {
78 if (Version == 2)
79 return AddrSize;
80 return getDwarfOffsetByteSize();
81 }
82
83 uint8_t getDwarfOffsetByteSize() const {
84 switch (Format) {
85 case dwarf::DwarfFormat::DWARF32:
86 return 4;
87 case dwarf::DwarfFormat::DWARF64:
88 return 8;
89 }
90 llvm_unreachable("Invalid Format value");
91 }
92 };
93
94 } // end anonymous namespace
95
96 template
97 static Optional getFixedByteSize(dwarf::Form Form, const T *U) {
61 Optional
62 DWARFFormValue::getFixedByteSize(dwarf::Form Form,
63 const DWARFFormParams &Params) {
9864 switch (Form) {
9965 case DW_FORM_addr:
100 if (U)
101 return U->getAddressByteSize();
102 return None;
66 assert(Params.Version && Params.AddrSize && "Invalid Params for form");
67 return Params.AddrSize;
10368
10469 case DW_FORM_block: // ULEB128 length L followed by L bytes.
10570 case DW_FORM_block1: // 1 byte length L followed by L bytes.
12085 return None;
12186
12287 case DW_FORM_ref_addr:
123 if (U)
124 return U->getRefAddrByteSize();
125 return None;
88 assert(Params.Version && Params.AddrSize && "Invalid Params for form");
89 return Params.getRefAddrByteSize();
12690
12791 case DW_FORM_flag:
12892 case DW_FORM_data1:
153117 case DW_FORM_line_strp:
154118 case DW_FORM_sec_offset:
155119 case DW_FORM_strp_sup:
156 if (U)
157 return U->getDwarfOffsetByteSize();
158 return None;
120 assert(Params.Version && Params.AddrSize && "Invalid Params for form");
121 return Params.getDwarfOffsetByteSize();
159122
160123 case DW_FORM_data8:
161124 case DW_FORM_ref8:
180143 return None;
181144 }
182145
183 template
184 static bool skipFormValue(dwarf::Form Form, const DataExtractor &DebugInfoData,
185 uint32_t *OffsetPtr, const T *U) {
146 bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
147 uint32_t *OffsetPtr,
148 const DWARFFormParams &Params) {
186149 bool Indirect = false;
187150 do {
188151 switch (Form) {
242205 case DW_FORM_line_strp:
243206 case DW_FORM_GNU_ref_alt:
244207 case DW_FORM_GNU_strp_alt:
245 if (Optional FixedSize = ::getFixedByteSize(Form, U)) {
208 if (Optional FixedSize =
209 DWARFFormValue::getFixedByteSize(Form, Params)) {
246210 *OffsetPtr += *FixedSize;
247211 return true;
248212 }
274238 }
275239 } while (Indirect);
276240 return true;
277 }
278
279 Optional DWARFFormValue::getFixedByteSize(dwarf::Form Form,
280 const DWARFUnit *U) {
281 return ::getFixedByteSize(Form, U);
282 }
283
284 Optional
285 DWARFFormValue::getFixedByteSize(dwarf::Form Form, uint16_t Version,
286 uint8_t AddrSize,
287 llvm::dwarf::DwarfFormat Format) {
288 FormSizeHelper FSH(Version, AddrSize, Format);
289 return ::getFixedByteSize(Form, &FSH);
290241 }
291242
292243 bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
447398 return true;
448399 }
449400
450 bool DWARFFormValue::skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr,
451 const DWARFUnit *U) const {
452 return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, U);
453 }
454
455 bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
456 uint32_t *OffsetPtr, const DWARFUnit *U) {
457 return skipFormValue(Form, DebugInfoData, OffsetPtr, U);
458 }
459
460 bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
461 uint32_t *OffsetPtr, uint16_t Version,
462 uint8_t AddrSize,
463 llvm::dwarf::DwarfFormat Format) {
464 FormSizeHelper FSH(Version, AddrSize, Format);
465 return skipFormValue(Form, DebugInfoData, OffsetPtr, &FSH);
466 }
467
468401 void DWARFFormValue::dump(raw_ostream &OS) const {
469402 uint64_t UValue = Value.uval;
470403 bool CURelativeOffset = false;
6161
6262 bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index,
6363 uint64_t &Result) const {
64 uint32_t Offset = AddrOffsetSectionBase + Index * AddrSize;
65 if (AddrOffsetSection->Data.size() < Offset + AddrSize)
66 return false;
67 DataExtractor DA(AddrOffsetSection->Data, isLittleEndian, AddrSize);
68 Result = getRelocatedValue(DA, AddrSize, &Offset, &AddrOffsetSection->Relocs);
64 uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize();
65 if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
66 return false;
67 DataExtractor DA(AddrOffsetSection->Data, isLittleEndian,
68 getAddressByteSize());
69 Result = getRelocatedValue(DA, getAddressByteSize(), &Offset,
70 &AddrOffsetSection->Relocs);
6971 return true;
7072 }
7173
9193
9294 bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) {
9395 Length = debug_info.getU32(offset_ptr);
94 Version = debug_info.getU16(offset_ptr);
96 // FIXME: Support DWARF64.
97 FormParams.Format = DWARF32;
98 FormParams.Version = debug_info.getU16(offset_ptr);
9599 uint64_t AbbrOffset;
96 if (Version >= 5) {
100 if (FormParams.Version >= 5) {
97101 UnitType = debug_info.getU8(offset_ptr);
98 AddrSize = debug_info.getU8(offset_ptr);
102 FormParams.AddrSize = debug_info.getU8(offset_ptr);
99103 AbbrOffset = debug_info.getU32(offset_ptr);
100104 } else {
101105 AbbrOffset = debug_info.getU32(offset_ptr);
102 AddrSize = debug_info.getU8(offset_ptr);
106 FormParams.AddrSize = debug_info.getU8(offset_ptr);
103107 }
104108 if (IndexEntry) {
105109 if (AbbrOffset)
114118 }
115119
116120 bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
117 bool VersionOK = DWARFContext::isSupportedVersion(Version);
118 bool AddrSizeOK = AddrSize == 4 || AddrSize == 8;
121 bool VersionOK = DWARFContext::isSupportedVersion(getVersion());
122 bool AddrSizeOK = getAddressByteSize() == 4 || getAddressByteSize() == 8;
119123
120124 if (!LengthOK || !VersionOK || !AddrSizeOK)
121125 return false;
122126
123127 // Keep track of the highest DWARF version we encounter across all units.
124 Context.setMaxVersionIfGreater(Version);
128 Context.setMaxVersionIfGreater(getVersion());
125129
126130 Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset);
127131 return Abbrevs != nullptr;
147151 DWARFDebugRangeList &RangeList) const {
148152 // Require that compile unit is extracted.
149153 assert(!DieArray.empty());
150 DataExtractor RangesData(RangeSection->Data, isLittleEndian, AddrSize);
154 DataExtractor RangesData(RangeSection->Data, isLittleEndian,
155 getAddressByteSize());
151156 uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
152157 return RangeList.extract(RangesData, &ActualRangeListOffset,
153158 RangeSection->Relocs);
156161 void DWARFUnit::clear() {
157162 Offset = 0;
158163 Length = 0;
159 Version = 0;
160164 Abbrevs = nullptr;
161 AddrSize = 0;
165 FormParams = DWARFFormParams({0, 0, DWARF32});
162166 BaseAddr = 0;
163167 RangeSectionBase = 0;
164168 AddrOffsetSectionBase = 0;
20622062 DataExtractor Data = Unit.getDebugInfoExtractor();
20632063
20642064 for (unsigned i = 0; i < Idx; ++i)
2065 DWARFFormValue::skipValue(Abbrev->getFormByIndex(i), Data, &Offset, &Unit);
2065 DWARFFormValue::skipValue(Abbrev->getFormByIndex(i), Data, &Offset,
2066 Unit.getFormParams());
20662067
20672068 uint32_t End = Offset;
2068 DWARFFormValue::skipValue(Abbrev->getFormByIndex(Idx), Data, &End, &Unit);
2069 DWARFFormValue::skipValue(Abbrev->getFormByIndex(Idx), Data, &End,
2070 Unit.getFormParams());
20692071
20702072 return std::make_pair(Offset, End);
20712073 }
22182220 DWARFFormValue Val(AttrSpec.Form);
22192221
22202222 if (!Val.isFormClass(DWARFFormValue::FC_Reference)) {
2221 DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset, &Unit);
2223 DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset,
2224 Unit.getFormParams());
22222225 continue;
22232226 }
22242227
27782781 for (const auto &AttrSpec : Abbrev->attributes()) {
27792782 if (shouldSkipAttribute(AttrSpec, Die->getTag(), Info.InDebugMap,
27802783 Flags & TF_SkipPC, Flags & TF_InFunctionScope)) {
2781 DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset, &U);
2784 DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset,
2785 U.getFormParams());
27822786 // FIXME: dsymutil-classic keeps the old abbreviation around
27832787 // even if it's not used. We can remove this (and the copyAbbrev
27842788 // helper) as soon as bit-for-bit compatibility is not a goal anymore.
30763080 // prologue over and that works because we act as both producer and
30773081 // consumer. It would be nicer to have a real configurable line
30783082 // table emitter.
3079 if (LineTable.Prologue.Version != 2 ||
3083 if (LineTable.Prologue.getVersion() != 2 ||
30803084 LineTable.Prologue.DefaultIsStmt != DWARF2_LINE_DEFAULT_IS_STMT ||
30813085 LineTable.Prologue.OpcodeBase > 13)
30823086 reportWarning("line table parameters mismatch. Cannot emit.");
181181 ID.Signature = InfoData.getU64(&Offset);
182182 break;
183183 default:
184 DWARFFormValue::skipValue(Form, InfoData, &Offset, Version, AddrSize,
185 Format);
184 DWARFFormValue::skipValue(Form, InfoData, &Offset,
185 DWARFFormParams({Version, AddrSize, Format}));
186186 }
187187 }
188188 return ID;
2222 TEST(DWARFFormValue, FixedFormSizes) {
2323 Optional RefSize;
2424 Optional AddrSize;
25
2526 // Test 32 bit DWARF version 2 with 4 byte addresses.
26 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 2, 4, DWARF32);
27 AddrSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 2, 4, DWARF32);
27 DWARFFormParams Params_2_4_32 = {2, 4, DWARF32};
28 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_2_4_32);
29 AddrSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_2_4_32);
2830 EXPECT_TRUE(RefSize.hasValue());
2931 EXPECT_TRUE(AddrSize.hasValue());
3032 EXPECT_EQ(*RefSize, *AddrSize);
3133
3234 // Test 32 bit DWARF version 2 with 8 byte addresses.
33 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 2, 8, DWARF32);
34 AddrSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 2, 8, DWARF32);
35 DWARFFormParams Params_2_8_32 = {2, 8, DWARF32};
36 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_2_8_32);
37 AddrSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_2_8_32);
3538 EXPECT_TRUE(RefSize.hasValue());
3639 EXPECT_TRUE(AddrSize.hasValue());
3740 EXPECT_EQ(*RefSize, *AddrSize);
3841
3942 // DW_FORM_ref_addr is 4 bytes in DWARF 32 in DWARF version 3 and beyond.
40 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 3, 4, DWARF32);
43 DWARFFormParams Params_3_4_32 = {3, 4, DWARF32};
44 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_3_4_32);
4145 EXPECT_TRUE(RefSize.hasValue());
4246 EXPECT_EQ(*RefSize, 4);
4347
44 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 4, 4, DWARF32);
48 DWARFFormParams Params_4_4_32 = {4, 4, DWARF32};
49 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_4_4_32);
4550 EXPECT_TRUE(RefSize.hasValue());
4651 EXPECT_EQ(*RefSize, 4);
4752
48 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 5, 4, DWARF32);
53 DWARFFormParams Params_5_4_32 = {5, 4, DWARF32};
54 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_5_4_32);
4955 EXPECT_TRUE(RefSize.hasValue());
5056 EXPECT_EQ(*RefSize, 4);
5157
5258 // DW_FORM_ref_addr is 8 bytes in DWARF 64 in DWARF version 3 and beyond.
53 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 3, 8, DWARF64);
59 DWARFFormParams Params_3_8_64 = {3, 8, DWARF64};
60 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_3_8_64);
5461 EXPECT_TRUE(RefSize.hasValue());
5562 EXPECT_EQ(*RefSize, 8);
5663
57 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 4, 8, DWARF64);
64 DWARFFormParams Params_4_8_64 = {4, 8, DWARF64};
65 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_4_8_64);
5866 EXPECT_TRUE(RefSize.hasValue());
5967 EXPECT_EQ(*RefSize, 8);
6068
61 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 5, 8, DWARF64);
69 DWARFFormParams Params_5_8_64 = {5, 8, DWARF64};
70 RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, Params_5_8_64);
6271 EXPECT_TRUE(RefSize.hasValue());
6372 EXPECT_EQ(*RefSize, 8);
6473 }