Skip to content

Commit 82f12b1

Browse files
author
Greg Clayton
committed
Clean up DWARFFormValue by reducing duplicated code and removing DWARFFormValue::getFixedFormSizes()
In preparation for a follow on patch that improves DWARF parsing speed, clean up DWARFFormValue so that we have can get the fixed byte size of a form value given a DWARFUnit or given the version, address byte size and dwarf32/64. This patch cleans up code so that everyone is using one of the new DWARFFormValue functions: static Optional<uint8_t> DWARFFormValue::getFixedByteSize(dwarf::Form Form, const DWARFUnit *U = nullptr); static Optional<uint8_t> DWARFFormValue::getFixedByteSize(dwarf::Form Form, uint16_t Version, uint8_t AddrSize, bool Dwarf32); This patch changes DWARFFormValue::skipValue() to rely on the output of DWARFFormValue::getFixedByteSize(...) instead of duplicating the code in each function. This will reduce the number of changes we need to make to DWARF to fewer places in DWARFFormValue when we add support for new form. This patch also starts to support DWARF64 so that we can get correct byte sizes for forms that vary according the DWARF 32/64. To reduce the code duplication a new FormSizeHelper pure virtual class was created that can be created as a FormSizeHelperDWARFUnit when you have a DWARFUnit, or FormSizeHelperManual where you manually specify the DWARF version, address byte size and DWARF32/DWARF64. There is now a single implementation of a function that gets the fixed byte size (instead of two where one took a DWARFUnit and one took the DWARF version, address byte size and DWARFFormat enum) and one function to skip the form values. https://reviews.llvm.org/D26526 llvm-svn: 286597
1 parent 2efc3cb commit 82f12b1

File tree

7 files changed

+369
-200
lines changed

7 files changed

+369
-200
lines changed

llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,79 @@ class DWARFFormValue {
8181
Optional<uint64_t> getAsAddress() const;
8282
Optional<uint64_t> getAsSectionOffset() const;
8383
Optional<ArrayRef<uint8_t>> getAsBlock() const;
84+
/// Get the fixed byte size for a given form.
85+
///
86+
/// If the form always has a fixed valid byte size that doesn't depend on a
87+
/// DWARFUnit, then an Optional with a value will be returned. If the form
88+
/// can vary in size depending on the DWARFUnit (DWARF version, address byte
89+
/// size, or DWARF 32/64) and the DWARFUnit is valid, then an Optional with a
90+
/// valid value is returned. If the form is always encoded using a variable
91+
/// length storage format (ULEB or SLEB numbers or blocks) or the size
92+
/// depends on a DWARFUnit and the DWARFUnit is NULL, then None will be
93+
/// returned.
94+
/// \param Form The DWARF form to get the fixed byte size for
95+
/// \param U The DWARFUnit that can be used to help determine the byte size.
96+
///
97+
/// \returns Optional<uint8_t> value with the fixed byte size or None if
98+
/// \p Form doesn't have a fixed byte size or a DWARFUnit wasn't supplied
99+
/// and was needed to calculate the byte size.
100+
static Optional<uint8_t> getFixedByteSize(dwarf::Form Form,
101+
const DWARFUnit *U = nullptr);
102+
/// Get the fixed byte size for a given form.
103+
///
104+
/// If the form has a fixed byte size given a valid DWARF version and address
105+
/// byte size, then an Optional with a valid value is returned. If the form
106+
/// is always encoded using a variable length storage format (ULEB or SLEB
107+
/// numbers or blocks) then None will be returned.
108+
///
109+
/// \param Form DWARF form to get the fixed byte size for
110+
/// \param Version DWARF version number.
111+
/// \param AddrSize size of an address in bytes.
112+
/// \param Format enum value from llvm::dwarf::DwarfFormat.
113+
/// \returns Optional<uint8_t> value with the fixed byte size or None if
114+
/// \p Form doesn't have a fixed byte size.
115+
static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, uint16_t Version,
116+
uint8_t AddrSize,
117+
llvm::dwarf::DwarfFormat Format);
84118

119+
/// Skip a form in \p debug_info_data at offset specified by \p offset_ptr.
120+
///
121+
/// Skips the bytes for this form in the debug info and updates the offset.
122+
///
123+
/// \param debug_info_data the .debug_info data to use to skip the value.
124+
/// \param offset_ptr a reference to the offset that will be updated.
125+
/// \param U the DWARFUnit to use when skipping the form in case the form
126+
/// size differs according to data in the DWARFUnit.
127+
/// \returns true on success, false if the form was not skipped.
85128
bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr,
86129
const DWARFUnit *U) const;
130+
/// Skip a form in \p debug_info_data at offset specified by \p offset_ptr.
131+
///
132+
/// Skips the bytes for this form in the debug info and updates the offset.
133+
///
134+
/// \param form the DW_FORM enumeration that indicates the form to skip.
135+
/// \param debug_info_data the .debug_info data to use to skip the value.
136+
/// \param offset_ptr a reference to the offset that will be updated.
137+
/// \param U the DWARFUnit to use when skipping the form in case the form
138+
/// size differs according to data in the DWARFUnit.
139+
/// \returns true on success, false if the form was not skipped.
87140
static bool skipValue(dwarf::Form form, DataExtractor debug_info_data,
88-
uint32_t *offset_ptr, const DWARFUnit *u);
141+
uint32_t *offset_ptr, const DWARFUnit *U);
142+
/// Skip a form in \p debug_info_data at offset specified by \p offset_ptr.
143+
///
144+
/// Skips the bytes for this form in the debug info and updates the offset.
145+
///
146+
/// \param form the DW_FORM enumeration that indicates the form to skip.
147+
/// \param debug_info_data the .debug_info data to use to skip the value.
148+
/// \param offset_ptr a reference to the offset that will be updated.
149+
/// \param Version DWARF version number.
150+
/// \param AddrSize size of an address in bytes.
151+
/// \param Format enum value from llvm::dwarf::DwarfFormat.
152+
/// \returns true on success, false if the form was not skipped.
89153
static bool skipValue(dwarf::Form form, DataExtractor debug_info_data,
90154
uint32_t *offset_ptr, uint16_t Version,
91-
uint8_t AddrSize);
155+
uint8_t AddrSize, llvm::dwarf::DwarfFormat Format);
92156

93-
static ArrayRef<uint8_t> getFixedFormSizes(uint8_t AddrSize,
94-
uint16_t Version);
95157
private:
96158
void dumpString(raw_ostream &OS) const;
97159
};

llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,25 @@ class DWARFUnit {
191191
uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
192192
uint32_t getLength() const { return Length; }
193193
uint16_t getVersion() const { return Version; }
194+
dwarf::DwarfFormat getFormat() const {
195+
return dwarf::DwarfFormat::DWARF32; // FIXME: Support DWARF64.
196+
}
194197
const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
195198
return Abbrevs;
196199
}
197200
uint8_t getAddressByteSize() const { return AddrSize; }
198201
uint8_t getRefAddrByteSize() const {
199-
// FIXME: Support DWARF64.
200-
return (Version == 2) ? AddrSize : 4;
202+
if (Version == 2)
203+
return AddrSize;
204+
return getDwarfOffsetByteSize();
205+
}
206+
uint8_t getDwarfOffsetByteSize() const {
207+
switch (getFormat()) {
208+
case dwarf::DwarfFormat::DWARF32:
209+
return 4;
210+
case dwarf::DwarfFormat::DWARF64:
211+
return 8;
212+
}
201213
}
202214
uint64_t getBaseAddress() const { return BaseAddr; }
203215

llvm/include/llvm/Support/Dwarf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,9 @@ struct PubIndexEntryDescriptor {
433433
};
434434
};
435435

436+
/// Constants that define the DWARF format as 32 or 64 bit.
437+
enum DwarfFormat { DWARF32, DWARF64 };
438+
436439
} // End of namespace dwarf
437440

438441
} // End of namespace llvm

llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -202,18 +202,13 @@ bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit *U,
202202
*OffsetPtr = Offset;
203203
return false;
204204
}
205-
ArrayRef<uint8_t> FixedFormSizes = DWARFFormValue::getFixedFormSizes(
206-
U->getAddressByteSize(), U->getVersion());
207-
assert(FixedFormSizes.size() > 0);
208205

209206
// Skip all data in the .debug_info for the attributes
210207
for (const auto &AttrSpec : AbbrevDecl->attributes()) {
211208
auto Form = AttrSpec.Form;
212209

213-
uint8_t FixedFormSize =
214-
(Form < FixedFormSizes.size()) ? FixedFormSizes[Form] : 0;
215-
if (FixedFormSize)
216-
*OffsetPtr += FixedFormSize;
210+
if (Optional<uint8_t> FixedSize = DWARFFormValue::getFixedByteSize(Form, U))
211+
*OffsetPtr += *FixedSize;
217212
else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, U)) {
218213
// Restore the original offset.
219214
*OffsetPtr = Offset;

0 commit comments

Comments
 (0)