forked from OSchip/llvm-project
[DebugInfo] Simplify DWARFDebugAddr.
The patch removes unnecessary members of DWARFDebugAddr and further simplifies the implementation by separating parsing methods of tables in the DWARFv5 and pre-standard formats. Differential Revision: https://reviews.llvm.org/D74197
This commit is contained in:
parent
de9604232a
commit
dc16612393
|
@ -27,69 +27,53 @@ class raw_ostream;
|
||||||
/// The table consists of a header followed by an array of address values from
|
/// The table consists of a header followed by an array of address values from
|
||||||
/// .debug_addr section.
|
/// .debug_addr section.
|
||||||
class DWARFDebugAddrTable {
|
class DWARFDebugAddrTable {
|
||||||
public:
|
|
||||||
struct Header {
|
|
||||||
/// The total length of the entries for this table, not including the length
|
|
||||||
/// field itself.
|
|
||||||
uint32_t Length = 0;
|
|
||||||
/// The DWARF version number.
|
|
||||||
uint16_t Version = 5;
|
|
||||||
/// The size in bytes of an address on the target architecture. For
|
|
||||||
/// segmented addressing, this is the size of the offset portion of the
|
|
||||||
/// address.
|
|
||||||
uint8_t AddrSize;
|
|
||||||
/// The size in bytes of a segment selector on the target architecture.
|
|
||||||
/// If the target system uses a flat address space, this value is 0.
|
|
||||||
uint8_t SegSize = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
dwarf::DwarfFormat Format;
|
dwarf::DwarfFormat Format;
|
||||||
uint64_t HeaderOffset;
|
uint64_t Offset;
|
||||||
Header HeaderData;
|
/// The total length of the entries for this table, not including the length
|
||||||
uint32_t DataSize = 0;
|
/// field itself.
|
||||||
|
uint32_t Length = 0;
|
||||||
|
/// The DWARF version number.
|
||||||
|
uint16_t Version;
|
||||||
|
/// The size in bytes of an address on the target architecture. For
|
||||||
|
/// segmented addressing, this is the size of the offset portion of the
|
||||||
|
/// address.
|
||||||
|
uint8_t AddrSize;
|
||||||
|
/// The size in bytes of a segment selector on the target architecture.
|
||||||
|
/// If the target system uses a flat address space, this value is 0.
|
||||||
|
uint8_t SegSize;
|
||||||
std::vector<uint64_t> Addrs;
|
std::vector<uint64_t> Addrs;
|
||||||
|
|
||||||
public:
|
/// Invalidate Length field to stop further processing.
|
||||||
void clear();
|
void invalidateLength() { Length = 0; }
|
||||||
|
|
||||||
/// Extract an entire table, including all addresses.
|
Error extractAddresses(const DWARFDataExtractor &Data, uint64_t *OffsetPtr,
|
||||||
Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr,
|
uint64_t EndOffset);
|
||||||
uint16_t Version, uint8_t AddrSize,
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Extract the entire table, including all addresses.
|
||||||
|
Error extract(const DWARFDataExtractor &Data, uint64_t *OffsetPtr,
|
||||||
|
uint16_t CUVersion, uint8_t CUAddrSize,
|
||||||
std::function<void(Error)> WarnCallback);
|
std::function<void(Error)> WarnCallback);
|
||||||
|
|
||||||
uint64_t getHeaderOffset() const { return HeaderOffset; }
|
/// Extract a DWARFv5 address table.
|
||||||
uint8_t getAddrSize() const { return HeaderData.AddrSize; }
|
Error extractV5(const DWARFDataExtractor &Data, uint64_t *OffsetPtr,
|
||||||
|
uint8_t CUAddrSize, std::function<void(Error)> WarnCallback);
|
||||||
|
|
||||||
|
/// Extract a pre-DWARFv5 address table. Such tables do not have a header
|
||||||
|
/// and consist only of a series of addresses.
|
||||||
|
/// See https://gcc.gnu.org/wiki/DebugFission for details.
|
||||||
|
Error extractPreStandard(const DWARFDataExtractor &Data, uint64_t *OffsetPtr,
|
||||||
|
uint16_t CUVersion, uint8_t CUAddrSize);
|
||||||
|
|
||||||
void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const;
|
void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const;
|
||||||
|
|
||||||
/// Return the address based on a given index.
|
/// Return the address based on a given index.
|
||||||
Expected<uint64_t> getAddrEntry(uint32_t Index) const;
|
Expected<uint64_t> getAddrEntry(uint32_t Index) const;
|
||||||
|
|
||||||
/// Return the size of the table header including the length
|
/// Return the full length of this table, including the length field.
|
||||||
/// but not including the addresses.
|
/// Return None if the length cannot be identified reliably.
|
||||||
uint8_t getHeaderSize() const {
|
Optional<uint64_t> getFullLength() const;
|
||||||
switch (Format) {
|
|
||||||
case dwarf::DwarfFormat::DWARF32:
|
|
||||||
return 8; // 4 + 2 + 1 + 1
|
|
||||||
case dwarf::DwarfFormat::DWARF64:
|
|
||||||
return 16; // 12 + 2 + 1 + 1
|
|
||||||
}
|
|
||||||
llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64)");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the length of this table, including the length field, or 0 if the
|
|
||||||
/// length has not been determined (e.g. because the table has not yet been
|
|
||||||
/// parsed, or there was a problem in parsing).
|
|
||||||
uint32_t getLength() const;
|
|
||||||
|
|
||||||
/// Verify that the given length is valid for this table.
|
|
||||||
bool hasValidLength() const { return getLength() != 0; }
|
|
||||||
|
|
||||||
/// Invalidate Length field to stop further processing.
|
|
||||||
void invalidateLength() { HeaderData.Length = 0; }
|
|
||||||
|
|
||||||
/// Returns the length of the array of addresses.
|
|
||||||
uint32_t getDataSize() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
|
@ -252,12 +252,13 @@ static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
|
||||||
WithColor::error() << toString(std::move(Err)) << '\n';
|
WithColor::error() << toString(std::move(Err)) << '\n';
|
||||||
// Keep going after an error, if we can, assuming that the length field
|
// Keep going after an error, if we can, assuming that the length field
|
||||||
// could be read. If it couldn't, stop reading the section.
|
// could be read. If it couldn't, stop reading the section.
|
||||||
if (!AddrTable.hasValidLength())
|
if (auto TableLength = AddrTable.getFullLength()) {
|
||||||
break;
|
Offset = TableOffset + *TableLength;
|
||||||
Offset = TableOffset + AddrTable.getLength();
|
continue;
|
||||||
} else {
|
}
|
||||||
AddrTable.dump(OS, DumpOpts);
|
break;
|
||||||
}
|
}
|
||||||
|
AddrTable.dump(OS, DumpOpts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,145 +12,146 @@
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
void DWARFDebugAddrTable::clear() {
|
Error DWARFDebugAddrTable::extractAddresses(const DWARFDataExtractor &Data,
|
||||||
HeaderData = {};
|
uint64_t *OffsetPtr,
|
||||||
|
uint64_t EndOffset) {
|
||||||
|
assert(EndOffset >= *OffsetPtr);
|
||||||
|
uint64_t DataSize = EndOffset - *OffsetPtr;
|
||||||
|
assert(Data.isValidOffsetForDataOfSize(*OffsetPtr, DataSize));
|
||||||
|
if (AddrSize != 4 && AddrSize != 8)
|
||||||
|
return createStringError(errc::not_supported,
|
||||||
|
"address table at offset 0x%" PRIx64
|
||||||
|
" has unsupported address size %" PRIu8
|
||||||
|
" (4 and 8 are supported)",
|
||||||
|
Offset, AddrSize);
|
||||||
|
if (DataSize % AddrSize != 0) {
|
||||||
|
invalidateLength();
|
||||||
|
return createStringError(errc::invalid_argument,
|
||||||
|
"address table at offset 0x%" PRIx64
|
||||||
|
" contains data of size 0x%" PRIx64
|
||||||
|
" which is not a multiple of addr size %" PRIu8,
|
||||||
|
Offset, DataSize, AddrSize);
|
||||||
|
}
|
||||||
Addrs.clear();
|
Addrs.clear();
|
||||||
invalidateLength();
|
size_t Count = DataSize / AddrSize;
|
||||||
|
Addrs.reserve(Count);
|
||||||
|
while (Count--)
|
||||||
|
Addrs.push_back(Data.getRelocatedValue(AddrSize, OffsetPtr));
|
||||||
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data,
|
Error DWARFDebugAddrTable::extractV5(const DWARFDataExtractor &Data,
|
||||||
uint64_t *OffsetPtr,
|
uint64_t *OffsetPtr, uint8_t CUAddrSize,
|
||||||
uint16_t Version,
|
std::function<void(Error)> WarnCallback) {
|
||||||
uint8_t AddrSize,
|
Offset = *OffsetPtr;
|
||||||
std::function<void(Error)> WarnCallback) {
|
// Check that we can read the unit length field.
|
||||||
clear();
|
if (!Data.isValidOffsetForDataOfSize(Offset, 4))
|
||||||
HeaderOffset = *OffsetPtr;
|
|
||||||
// Read and verify the length field.
|
|
||||||
if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, sizeof(uint32_t)))
|
|
||||||
return createStringError(errc::invalid_argument,
|
return createStringError(errc::invalid_argument,
|
||||||
"section is not large enough to contain an "
|
"section is not large enough to contain an "
|
||||||
"address table length at offset 0x%"
|
"address table length at offset 0x%" PRIx64,
|
||||||
PRIx64, *OffsetPtr);
|
Offset);
|
||||||
uint16_t UnitVersion;
|
|
||||||
if (Version == 0) {
|
|
||||||
WarnCallback(createStringError(errc::invalid_argument,
|
|
||||||
"DWARF version is not defined in CU,"
|
|
||||||
" assuming version 5"));
|
|
||||||
UnitVersion = 5;
|
|
||||||
} else {
|
|
||||||
UnitVersion = Version;
|
|
||||||
}
|
|
||||||
// TODO: Add support for DWARF64.
|
// TODO: Add support for DWARF64.
|
||||||
Format = dwarf::DwarfFormat::DWARF32;
|
Format = dwarf::DwarfFormat::DWARF32;
|
||||||
if (UnitVersion >= 5) {
|
Length = Data.getU32(OffsetPtr);
|
||||||
HeaderData.Length = Data.getU32(OffsetPtr);
|
if (Length == dwarf::DW_LENGTH_DWARF64) {
|
||||||
if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64) {
|
invalidateLength();
|
||||||
invalidateLength();
|
return createStringError(
|
||||||
return createStringError(errc::not_supported,
|
errc::not_supported,
|
||||||
"DWARF64 is not supported in .debug_addr at offset 0x%" PRIx64,
|
"DWARF64 is not supported in .debug_addr at offset 0x%" PRIx64, Offset);
|
||||||
HeaderOffset);
|
|
||||||
}
|
|
||||||
if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header)) {
|
|
||||||
uint32_t TmpLength = HeaderData.Length;
|
|
||||||
invalidateLength();
|
|
||||||
return createStringError(errc::invalid_argument,
|
|
||||||
"address table at offset 0x%" PRIx64
|
|
||||||
" has a unit_length value of 0x%" PRIx32
|
|
||||||
", which is too small to contain a complete header",
|
|
||||||
HeaderOffset, TmpLength);
|
|
||||||
}
|
|
||||||
uint64_t End = HeaderOffset + getLength();
|
|
||||||
if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset)) {
|
|
||||||
uint32_t TmpLength = HeaderData.Length;
|
|
||||||
invalidateLength();
|
|
||||||
return createStringError(
|
|
||||||
errc::invalid_argument,
|
|
||||||
"section is not large enough to contain an address table "
|
|
||||||
"at offset 0x%" PRIx64 " with a unit_length value of 0x%" PRIx32,
|
|
||||||
HeaderOffset, TmpLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
HeaderData.Version = Data.getU16(OffsetPtr);
|
|
||||||
HeaderData.AddrSize = Data.getU8(OffsetPtr);
|
|
||||||
HeaderData.SegSize = Data.getU8(OffsetPtr);
|
|
||||||
DataSize = getDataSize();
|
|
||||||
} else {
|
|
||||||
HeaderData.Version = UnitVersion;
|
|
||||||
HeaderData.AddrSize = AddrSize;
|
|
||||||
// TODO: Support for non-zero SegSize.
|
|
||||||
HeaderData.SegSize = 0;
|
|
||||||
DataSize = Data.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform basic validation of the remaining header fields.
|
if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, Length)) {
|
||||||
|
uint32_t DiagnosticLength = Length;
|
||||||
|
invalidateLength();
|
||||||
|
return createStringError(
|
||||||
|
errc::invalid_argument,
|
||||||
|
"section is not large enough to contain an address table "
|
||||||
|
"at offset 0x%" PRIx64 " with a unit_length value of 0x%" PRIx32,
|
||||||
|
Offset, DiagnosticLength);
|
||||||
|
}
|
||||||
|
uint64_t EndOffset = *OffsetPtr + Length;
|
||||||
|
// Ensure that we can read the remaining header fields.
|
||||||
|
if (Length < 4) {
|
||||||
|
uint32_t DiagnosticLength = Length;
|
||||||
|
invalidateLength();
|
||||||
|
return createStringError(
|
||||||
|
errc::invalid_argument,
|
||||||
|
"address table at offset 0x%" PRIx64
|
||||||
|
" has a unit_length value of 0x%" PRIx32
|
||||||
|
", which is too small to contain a complete header",
|
||||||
|
Offset, DiagnosticLength);
|
||||||
|
}
|
||||||
|
|
||||||
// We support DWARF version 5 for now as well as pre-DWARF5
|
Version = Data.getU16(OffsetPtr);
|
||||||
// implementations of .debug_addr table, which doesn't contain a header
|
AddrSize = Data.getU8(OffsetPtr);
|
||||||
// and consists only of a series of addresses.
|
SegSize = Data.getU8(OffsetPtr);
|
||||||
if (HeaderData.Version > 5) {
|
|
||||||
|
// Perform a basic validation of the header fields.
|
||||||
|
if (Version != 5)
|
||||||
return createStringError(errc::not_supported,
|
return createStringError(errc::not_supported,
|
||||||
"address table at offset 0x%" PRIx64
|
"address table at offset 0x%" PRIx64
|
||||||
" has unsupported version %" PRIu16,
|
" has unsupported version %" PRIu16,
|
||||||
HeaderOffset, HeaderData.Version);
|
Offset, Version);
|
||||||
}
|
// TODO: add support for non-zero segment selector size.
|
||||||
// FIXME: For now we just treat version mismatch as an error,
|
if (SegSize != 0)
|
||||||
// however the correct way to associate a .debug_addr table
|
|
||||||
// with a .debug_info table is to look at the DW_AT_addr_base
|
|
||||||
// attribute in the info table.
|
|
||||||
if (HeaderData.Version != UnitVersion)
|
|
||||||
return createStringError(errc::invalid_argument,
|
|
||||||
"address table at offset 0x%" PRIx64
|
|
||||||
" has version %" PRIu16
|
|
||||||
" which is different from the version suggested"
|
|
||||||
" by the DWARF unit header: %" PRIu16,
|
|
||||||
HeaderOffset, HeaderData.Version, UnitVersion);
|
|
||||||
if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
|
|
||||||
return createStringError(errc::not_supported,
|
return createStringError(errc::not_supported,
|
||||||
"address table at offset 0x%" PRIx64
|
"address table at offset 0x%" PRIx64
|
||||||
" has unsupported address size %" PRIu8
|
" has unsupported segment selector size %" PRIu8,
|
||||||
" (4 and 8 are supported)",
|
Offset, SegSize);
|
||||||
HeaderOffset, HeaderData.AddrSize);
|
|
||||||
if (HeaderData.AddrSize != AddrSize && AddrSize != 0)
|
if (Error Err = extractAddresses(Data, OffsetPtr, EndOffset))
|
||||||
|
return Err;
|
||||||
|
if (CUAddrSize && AddrSize != CUAddrSize) {
|
||||||
WarnCallback(createStringError(
|
WarnCallback(createStringError(
|
||||||
errc::invalid_argument,
|
errc::invalid_argument,
|
||||||
"address table at offset 0x%" PRIx64 " has address size %" PRIu8
|
"address table at offset 0x%" PRIx64 " has address size %" PRIu8
|
||||||
" which is different from CU address size %" PRIu8,
|
" which is different from CU address size %" PRIu8,
|
||||||
HeaderOffset, HeaderData.AddrSize, AddrSize));
|
Offset, AddrSize, CUAddrSize));
|
||||||
|
|
||||||
// TODO: add support for non-zero segment selector size.
|
|
||||||
if (HeaderData.SegSize != 0)
|
|
||||||
return createStringError(errc::not_supported,
|
|
||||||
"address table at offset 0x%" PRIx64
|
|
||||||
" has unsupported segment selector size %" PRIu8,
|
|
||||||
HeaderOffset, HeaderData.SegSize);
|
|
||||||
if (DataSize % HeaderData.AddrSize != 0) {
|
|
||||||
invalidateLength();
|
|
||||||
return createStringError(errc::invalid_argument,
|
|
||||||
"address table at offset 0x%" PRIx64
|
|
||||||
" contains data of size %" PRIu32
|
|
||||||
" which is not a multiple of addr size %" PRIu8,
|
|
||||||
HeaderOffset, DataSize, HeaderData.AddrSize);
|
|
||||||
}
|
}
|
||||||
Data.setAddressSize(HeaderData.AddrSize);
|
|
||||||
uint32_t AddrCount = DataSize / HeaderData.AddrSize;
|
|
||||||
for (uint32_t I = 0; I < AddrCount; ++I)
|
|
||||||
Addrs.push_back(Data.getRelocatedAddress(OffsetPtr));
|
|
||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error DWARFDebugAddrTable::extractPreStandard(const DWARFDataExtractor &Data,
|
||||||
|
uint64_t *OffsetPtr,
|
||||||
|
uint16_t CUVersion,
|
||||||
|
uint8_t CUAddrSize) {
|
||||||
|
assert(CUVersion > 0 && CUVersion < 5);
|
||||||
|
|
||||||
|
Offset = *OffsetPtr;
|
||||||
|
Length = 0;
|
||||||
|
Version = CUVersion;
|
||||||
|
AddrSize = CUAddrSize;
|
||||||
|
SegSize = 0;
|
||||||
|
|
||||||
|
return extractAddresses(Data, OffsetPtr, Data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
Error DWARFDebugAddrTable::extract(const DWARFDataExtractor &Data,
|
||||||
|
uint64_t *OffsetPtr,
|
||||||
|
uint16_t CUVersion,
|
||||||
|
uint8_t CUAddrSize,
|
||||||
|
std::function<void(Error)> WarnCallback) {
|
||||||
|
if (CUVersion > 0 && CUVersion < 5)
|
||||||
|
return extractPreStandard(Data, OffsetPtr, CUVersion, CUAddrSize);
|
||||||
|
if (CUVersion == 0)
|
||||||
|
WarnCallback(createStringError(errc::invalid_argument,
|
||||||
|
"DWARF version is not defined in CU,"
|
||||||
|
" assuming version 5"));
|
||||||
|
return extractV5(Data, OffsetPtr, CUAddrSize, WarnCallback);
|
||||||
|
}
|
||||||
|
|
||||||
void DWARFDebugAddrTable::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
|
void DWARFDebugAddrTable::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
|
||||||
if (DumpOpts.Verbose)
|
if (DumpOpts.Verbose)
|
||||||
OS << format("0x%8.8" PRIx32 ": ", HeaderOffset);
|
OS << format("0x%8.8" PRIx32 ": ", Offset);
|
||||||
if (HeaderData.Length)
|
if (Length)
|
||||||
OS << format("Address table header: length = 0x%8.8" PRIx32
|
OS << format("Address table header: length = 0x%8.8" PRIx32
|
||||||
", version = 0x%4.4" PRIx16 ", "
|
", version = 0x%4.4" PRIx16 ", addr_size = 0x%2.2" PRIx8
|
||||||
"addr_size = 0x%2.2" PRIx8 ", seg_size = 0x%2.2" PRIx8 "\n",
|
", seg_size = 0x%2.2" PRIx8 "\n",
|
||||||
HeaderData.Length, HeaderData.Version, HeaderData.AddrSize,
|
Length, Version, AddrSize, SegSize);
|
||||||
HeaderData.SegSize);
|
|
||||||
|
|
||||||
if (Addrs.size() > 0) {
|
if (Addrs.size() > 0) {
|
||||||
const char *AddrFmt = (HeaderData.AddrSize == 4) ? "0x%8.8" PRIx64 "\n"
|
const char *AddrFmt =
|
||||||
: "0x%16.16" PRIx64 "\n";
|
(AddrSize == 4) ? "0x%8.8" PRIx64 "\n" : "0x%16.16" PRIx64 "\n";
|
||||||
OS << "Addrs: [\n";
|
OS << "Addrs: [\n";
|
||||||
for (uint64_t Addr : Addrs)
|
for (uint64_t Addr : Addrs)
|
||||||
OS << format(AddrFmt, Addr);
|
OS << format(AddrFmt, Addr);
|
||||||
|
@ -162,22 +163,15 @@ Expected<uint64_t> DWARFDebugAddrTable::getAddrEntry(uint32_t Index) const {
|
||||||
if (Index < Addrs.size())
|
if (Index < Addrs.size())
|
||||||
return Addrs[Index];
|
return Addrs[Index];
|
||||||
return createStringError(errc::invalid_argument,
|
return createStringError(errc::invalid_argument,
|
||||||
"Index %" PRIu32 " is out of range in the "
|
"Index %" PRIu32 " is out of range of the "
|
||||||
"address table at offset 0x%" PRIx64,
|
"address table at offset 0x%" PRIx64,
|
||||||
Index, HeaderOffset);
|
Index, Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t DWARFDebugAddrTable::getLength() const {
|
Optional<uint64_t> DWARFDebugAddrTable::getFullLength() const {
|
||||||
if (HeaderData.Length == 0)
|
if (Length == 0)
|
||||||
return 0;
|
return None;
|
||||||
// TODO: DWARF64 support.
|
// TODO: DWARF64 support.
|
||||||
return HeaderData.Length + sizeof(uint32_t);
|
return Length + sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t DWARFDebugAddrTable::getDataSize() const {
|
|
||||||
if (DataSize != 0)
|
|
||||||
return DataSize;
|
|
||||||
if (getLength() == 0)
|
|
||||||
return 0;
|
|
||||||
return getLength() - getHeaderSize();
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
# CHECK: .debug_addr contents:
|
# CHECK: .debug_addr contents:
|
||||||
# CHECK-NOT: {{.}}
|
# CHECK-NOT: {{.}}
|
||||||
# ERR: address table at offset 0x0 contains data of size 7 which is not a multiple of addr size 4
|
# ERR: address table at offset 0x0 contains data of size 0x7 which is not a multiple of addr size 4
|
||||||
# ERR-NOT: {{.}}
|
# ERR-NOT: {{.}}
|
||||||
|
|
||||||
# data size is not multiple of address_size
|
# data size is not multiple of address_size
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
# RUN: FileCheck %s -input-file %t.err -check-prefix=ERR
|
# RUN: FileCheck %s -input-file %t.err -check-prefix=ERR
|
||||||
|
|
||||||
# ERR: address table at offset 0x0 has unsupported version 6
|
# ERR: address table at offset 0x0 has unsupported version 6
|
||||||
|
# ERR: address table at offset 0x20 has unsupported version 4
|
||||||
# ERR-NOT: {{.}}
|
# ERR-NOT: {{.}}
|
||||||
|
|
||||||
# CHECK: .debug_addr contents
|
# CHECK: .debug_addr contents
|
||||||
|
@ -40,3 +41,13 @@
|
||||||
.byte 0 # segment_selector_size
|
.byte 0 # segment_selector_size
|
||||||
.long 0x00000002
|
.long 0x00000002
|
||||||
.long 0x00000003
|
.long 0x00000003
|
||||||
|
|
||||||
|
.section .debug_addr,"",@progbits
|
||||||
|
.Ldebug_addr2:
|
||||||
|
.long 12 # unit_length = .short + .byte + .byte + .long + .long
|
||||||
|
.short 4 # version
|
||||||
|
.byte 4 # address_size
|
||||||
|
.byte 0 # segment_selector_size
|
||||||
|
.long 0x00000000
|
||||||
|
.long 0x00000001
|
||||||
|
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
# RUN: llvm-mc %s -filetype obj -triple i386-pc-linux -o - | \
|
|
||||||
# RUN: llvm-dwarfdump -debug-addr - 2> %t.err | FileCheck %s
|
|
||||||
# RUN: FileCheck %s -input-file %t.err -check-prefix=ERR
|
|
||||||
|
|
||||||
# ERR: address table at offset 0x0 has version 4 which is different from the version suggested by the DWARF unit header: 5
|
|
||||||
# ERR-NOT: {{.}}
|
|
||||||
|
|
||||||
# CHECK: .debug_addr contents
|
|
||||||
# CHECK-NEXT: length = 0x0000000c, version = 0x0005, addr_size = 0x04, seg_size = 0x00
|
|
||||||
# CHECK-NEXT: Addrs: [
|
|
||||||
# CHECK-NEXT: 0x00000000
|
|
||||||
# CHECK-NEXT: 0x00000001
|
|
||||||
# CHECK-NEXT: ]
|
|
||||||
# CHECK-NOT: {{.}}
|
|
||||||
|
|
||||||
.section .debug_abbrev,"",@progbits
|
|
||||||
.byte 1 # Abbreviation Code
|
|
||||||
.section .debug_info,"",@progbits
|
|
||||||
.Lcu_begin0:
|
|
||||||
.long 8 # Length of Unit
|
|
||||||
.short 5 # DWARF version number
|
|
||||||
.byte 1 # DWARF unit type
|
|
||||||
.byte 4 # Address Size (in bytes)
|
|
||||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
|
||||||
|
|
||||||
.section .debug_addr,"",@progbits
|
|
||||||
.Ldebug_addr0:
|
|
||||||
.long 12 # unit_length = .short + .byte + .byte + .long + .long
|
|
||||||
.short 4 # version
|
|
||||||
.byte 4 # address_size
|
|
||||||
.byte 0 # segment_selector_size
|
|
||||||
.long 0x00000000
|
|
||||||
.long 0x00000001
|
|
||||||
|
|
||||||
.section .debug_addr,"",@progbits
|
|
||||||
.Ldebug_addr1:
|
|
||||||
.long 12 # unit_length = .short + .byte + .byte + .long + .long
|
|
||||||
.short 5 # version
|
|
||||||
.byte 4 # address_size
|
|
||||||
.byte 0 # segment_selector_size
|
|
||||||
.long 0x00000000
|
|
||||||
.long 0x00000001
|
|
Loading…
Reference in New Issue