Use DWARFDataExtractor::getInitialLength in debug_aranges

Summary:
getInitialLength is a *DWARF*DataExtractor method so I had to "upgrade"
some DataExtractors to be able to make use of it.

Reviewers: ikudrin, jhenderson, probinson

Subscribers: aprantl, hiraditya, llvm-commits, dblaikie

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D75535
This commit is contained in:
Pavel Labath 2020-03-02 12:48:59 +01:00
parent 38385630ad
commit eb2b17eea7
7 changed files with 38 additions and 64 deletions

View File

@ -10,7 +10,7 @@
#define LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H #define LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H
#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/iterator_range.h"
#include "llvm/Support/DataExtractor.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/Support/Error.h" #include "llvm/Support/Error.h"
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
@ -58,7 +58,7 @@ public:
DWARFDebugArangeSet() { clear(); } DWARFDebugArangeSet() { clear(); }
void clear(); void clear();
Error extract(DataExtractor data, uint64_t *offset_ptr); Error extract(DWARFDataExtractor data, uint64_t *offset_ptr);
void dump(raw_ostream &OS) const; void dump(raw_ostream &OS) const;
uint64_t getCompileUnitDIEOffset() const { return HeaderData.CuOffset; } uint64_t getCompileUnitDIEOffset() const { return HeaderData.CuOffset; }

View File

@ -10,7 +10,7 @@
#define LLVM_DEBUGINFO_DWARFDEBUGARANGES_H #define LLVM_DEBUGINFO_DWARFDEBUGARANGES_H
#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/DenseSet.h"
#include "llvm/Support/DataExtractor.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
@ -25,7 +25,7 @@ public:
private: private:
void clear(); void clear();
void extract(DataExtractor DebugArangesData, void extract(DWARFDataExtractor DebugArangesData,
function_ref<void(Error)> RecoverableErrorHandler); function_ref<void(Error)> RecoverableErrorHandler);
/// Call appendRange multiple times and then call construct. /// Call appendRange multiple times and then call construct.

View File

@ -457,7 +457,8 @@ void DWARFContext::dump(
if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges, if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
DObj->getArangesSection())) { DObj->getArangesSection())) {
uint64_t offset = 0; uint64_t offset = 0;
DataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(), 0); DWARFDataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(),
0);
DWARFDebugArangeSet set; DWARFDebugArangeSet set;
while (arangesData.isValidOffset(offset)) { while (arangesData.isValidOffset(offset)) {
if (Error E = set.extract(arangesData, &offset)) { if (Error E = set.extract(arangesData, &offset)) {

View File

@ -31,7 +31,8 @@ void DWARFDebugArangeSet::clear() {
ArangeDescriptors.clear(); ArangeDescriptors.clear();
} }
Error DWARFDebugArangeSet::extract(DataExtractor data, uint64_t *offset_ptr) { Error DWARFDebugArangeSet::extract(DWARFDataExtractor data,
uint64_t *offset_ptr) {
assert(data.isValidOffset(*offset_ptr)); assert(data.isValidOffset(*offset_ptr));
ArangeDescriptors.clear(); ArangeDescriptors.clear();
Offset = *offset_ptr; Offset = *offset_ptr;
@ -59,45 +60,20 @@ Error DWARFDebugArangeSet::extract(DataExtractor data, uint64_t *offset_ptr) {
// the segment selectors are omitted from all tuples, including // the segment selectors are omitted from all tuples, including
// the terminating tuple. // the terminating tuple.
constexpr unsigned CommonFieldsLength = 2 + // Version dwarf::DwarfFormat format;
1 + // Address Size Error Err = Error::success();
1; // Segment Selector Size std::tie(HeaderData.Length, format) = data.getInitialLength(offset_ptr, &Err);
static const unsigned DWARF32HeaderLength = HeaderData.Version = data.getU16(offset_ptr, &Err);
dwarf::getUnitLengthFieldByteSize(dwarf::DWARF32) + CommonFieldsLength +
dwarf::getDwarfOffsetByteSize(dwarf::DWARF32); // Debug Info Offset
static const unsigned DWARF64HeaderLength =
dwarf::getUnitLengthFieldByteSize(dwarf::DWARF64) + CommonFieldsLength +
dwarf::getDwarfOffsetByteSize(dwarf::DWARF64); // Debug Info Offset
if (!data.isValidOffsetForDataOfSize(Offset, DWARF32HeaderLength))
return createStringError(errc::invalid_argument,
"section is not large enough to contain "
"an address range table at offset 0x%" PRIx64,
Offset);
dwarf::DwarfFormat format = dwarf::DWARF32;
HeaderData.Length = data.getU32(offset_ptr);
if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64) {
if (!data.isValidOffsetForDataOfSize(Offset, DWARF64HeaderLength))
return createStringError(
errc::invalid_argument,
"section is not large enough to contain a DWARF64 "
"address range table at offset 0x%" PRIx64,
Offset);
HeaderData.Length = data.getU64(offset_ptr);
format = dwarf::DWARF64;
} else if (HeaderData.Length >= dwarf::DW_LENGTH_lo_reserved) {
return createStringError(
errc::invalid_argument,
"address range table at offset 0x%" PRIx64
" has unsupported reserved unit length of value 0x%8.8" PRIx64,
Offset, HeaderData.Length);
}
HeaderData.Version = data.getU16(offset_ptr);
HeaderData.CuOffset = HeaderData.CuOffset =
data.getUnsigned(offset_ptr, dwarf::getDwarfOffsetByteSize(format)); data.getUnsigned(offset_ptr, dwarf::getDwarfOffsetByteSize(format), &Err);
HeaderData.AddrSize = data.getU8(offset_ptr); HeaderData.AddrSize = data.getU8(offset_ptr, &Err);
HeaderData.SegSize = data.getU8(offset_ptr); HeaderData.SegSize = data.getU8(offset_ptr, &Err);
if (Err) {
return createStringError(errc::invalid_argument,
"parsing address ranges table at offset 0x%" PRIx64
": %s",
Offset, toString(std::move(Err)).c_str());
}
// Perform basic validation of the header fields. // Perform basic validation of the header fields.
uint64_t full_length = uint64_t full_length =

View File

@ -20,7 +20,7 @@
using namespace llvm; using namespace llvm;
void DWARFDebugAranges::extract( void DWARFDebugAranges::extract(
DataExtractor DebugArangesData, DWARFDataExtractor DebugArangesData,
function_ref<void(Error)> RecoverableErrorHandler) { function_ref<void(Error)> RecoverableErrorHandler) {
if (!DebugArangesData.isValidOffset(0)) if (!DebugArangesData.isValidOffset(0))
return; return;
@ -48,8 +48,8 @@ void DWARFDebugAranges::generate(DWARFContext *CTX) {
return; return;
// Extract aranges from .debug_aranges section. // Extract aranges from .debug_aranges section.
DataExtractor ArangesData(CTX->getDWARFObj().getArangesSection(), DWARFDataExtractor ArangesData(CTX->getDWARFObj().getArangesSection(),
CTX->isLittleEndian(), 0); CTX->isLittleEndian(), 0);
extract(ArangesData, CTX->getRecoverableErrorHandler()); extract(ArangesData, CTX->getRecoverableErrorHandler());
// Generate aranges from DIEs: even if .debug_aranges section is present, // Generate aranges from DIEs: even if .debug_aranges section is present,

View File

@ -57,8 +57,8 @@ void dumpDebugStrings(DWARFContext &DCtx, DWARFYAML::Data &Y) {
} }
Error dumpDebugARanges(DWARFContext &DCtx, DWARFYAML::Data &Y) { Error dumpDebugARanges(DWARFContext &DCtx, DWARFYAML::Data &Y) {
DataExtractor ArangesData(DCtx.getDWARFObj().getArangesSection(), DWARFDataExtractor ArangesData(DCtx.getDWARFObj().getArangesSection(),
DCtx.isLittleEndian(), 0); DCtx.isLittleEndian(), 0);
uint64_t Offset = 0; uint64_t Offset = 0;
DWARFDebugArangeSet Set; DWARFDebugArangeSet Set;

View File

@ -16,9 +16,9 @@ namespace {
template <size_t SecSize> template <size_t SecSize>
void ExpectExtractError(const char (&SecDataRaw)[SecSize], void ExpectExtractError(const char (&SecDataRaw)[SecSize],
const char *ErrorMessage) { const char *ErrorMessage) {
DataExtractor Extractor(StringRef(SecDataRaw, SecSize - 1), DWARFDataExtractor Extractor(StringRef(SecDataRaw, SecSize - 1),
/* IsLittleEndian = */ true, /* IsLittleEndian = */ true,
/* AddressSize = */ 4); /* AddressSize = */ 4);
DWARFDebugArangeSet Set; DWARFDebugArangeSet Set;
uint64_t Offset = 0; uint64_t Offset = 0;
Error E = Set.extract(Extractor, &Offset); Error E = Set.extract(Extractor, &Offset);
@ -111,29 +111,26 @@ TEST(DWARFDebugArangeSet, ReservedUnitLength) {
// the section. 1 will be automatically subtracted in ExpectExtractError(). // the section. 1 will be automatically subtracted in ExpectExtractError().
static const char DebugArangesSecRaw[12 + 1] = static const char DebugArangesSecRaw[12 + 1] =
"\xf0\xff\xff\xff"; // Reserved unit length value "\xf0\xff\xff\xff"; // Reserved unit length value
ExpectExtractError( ExpectExtractError(DebugArangesSecRaw,
DebugArangesSecRaw, "parsing address ranges table at offset 0x0: unsupported "
"address range table at offset 0x0 has unsupported reserved unit length " "reserved unit length of value 0xfffffff0");
"of value 0xfffffff0");
} }
TEST(DWARFDebugArangeSet, SectionTooShort) { TEST(DWARFDebugArangeSet, SectionTooShort) {
// Note: 1 will be automatically subtracted in ExpectExtractError(). // Note: 1 will be automatically subtracted in ExpectExtractError().
static const char DebugArangesSecRaw[11 + 1] = {0}; static const char DebugArangesSecRaw[11 + 1] = {0};
ExpectExtractError( ExpectExtractError(DebugArangesSecRaw,
DebugArangesSecRaw, "parsing address ranges table at offset 0x0: unexpected "
"section is not large enough to contain an address range table " "end of data at offset 0xb");
"at offset 0x0");
} }
TEST(DWARFDebugArangeSet, SectionTooShortDWARF64) { TEST(DWARFDebugArangeSet, SectionTooShortDWARF64) {
// Note: 1 will be automatically subtracted in ExpectExtractError(). // Note: 1 will be automatically subtracted in ExpectExtractError().
static const char DebugArangesSecRaw[23 + 1] = static const char DebugArangesSecRaw[23 + 1] =
"\xff\xff\xff\xff"; // DWARF64 mark "\xff\xff\xff\xff"; // DWARF64 mark
ExpectExtractError( ExpectExtractError(DebugArangesSecRaw,
DebugArangesSecRaw, "parsing address ranges table at offset 0x0: unexpected "
"section is not large enough to contain a DWARF64 address range table " "end of data at offset 0x17");
"at offset 0x0");
} }
TEST(DWARFDebugArangeSet, NoSpaceForEntries) { TEST(DWARFDebugArangeSet, NoSpaceForEntries) {