mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-05 17:12:00 +00:00
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:
parent
38385630ad
commit
eb2b17eea7
@ -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; }
|
||||||
|
@ -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.
|
||||||
|
@ -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)) {
|
||||||
|
@ -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 =
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user