1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00

[DWARF] Support for .debug_addr (consumer)

This patch implements basic support for parsing
  and dumping DWARFv5 .debug_addr section.

llvm-svn: 338447
This commit is contained in:
Victor Leschuk 2018-07-31 22:19:19 +00:00
parent 4cfa35105e
commit 83ecc100c7
23 changed files with 702 additions and 10 deletions

View File

@ -856,6 +856,7 @@ HANDLE_DW_UT(0x06, split_type)
// TODO: Add Mach-O and COFF names.
// Official DWARF sections.
HANDLE_DWARF_SECTION(DebugAbbrev, ".debug_abbrev", "debug-abbrev")
HANDLE_DWARF_SECTION(DebugAddr, ".debug_addr", "debug-addr")
HANDLE_DWARF_SECTION(DebugAranges, ".debug_aranges", "debug-aranges")
HANDLE_DWARF_SECTION(DebugInfo, ".debug_info", "debug-info")
HANDLE_DWARF_SECTION(DebugTypes, ".debug_types", "debug-types")

View File

@ -154,6 +154,8 @@ enum DIDumpType : unsigned {
struct DIDumpOptions {
unsigned DumpType = DIDT_All;
unsigned RecurseDepth = -1U;
uint16_t Version = 0; // DWARF version to assume when extracting.
uint8_t AddrSize = 4; // Address byte size to assume when extracting.
bool ShowAddresses = true;
bool ShowChildren = false;
bool ShowParents = false;

View File

@ -323,6 +323,10 @@ public:
/// have initialized the relevant target descriptions.
Error loadRegisterInfo(const object::ObjectFile &Obj);
/// Get address size from CUs.
/// TODO: refactor compile_units() to make this const.
uint8_t getCUAddrSize();
private:
/// Return the compile unit which contains instruction with provided
/// address.

View File

@ -51,6 +51,8 @@ public:
/// reflect the absolute address of this pointer.
Optional<uint64_t> getEncodedPointer(uint32_t *Offset, uint8_t Encoding,
uint64_t AbsPosOffset = 0) const;
size_t size() const { return Section == nullptr ? 0 : Section->Data.size(); }
};
} // end namespace llvm

View File

@ -0,0 +1,98 @@
//===- DWARFDebugAddr.h -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_DWARFDEBUGADDR_H
#define LLVM_DEBUGINFO_DWARFDEBUGADDR_H
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include <cstdint>
#include <map>
#include <vector>
namespace llvm {
class Error;
class raw_ostream;
/// A class representing an address table as specified in DWARF v5.
/// The table consists of a header followed by an array of address values from
/// .debug_addr section.
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;
uint32_t HeaderOffset;
Header HeaderData;
uint32_t DataSize = 0;
std::vector<uint64_t> Addrs;
public:
void clear();
/// Extract an entire table, including all addresses.
Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr,
uint16_t Version, uint8_t AddrSize,
std::function<void(Error)> WarnCallback);
uint32_t getHeaderOffset() const { return HeaderOffset; }
uint8_t getAddrSize() const { return HeaderData.AddrSize; }
void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const;
/// Return the address based on a given index.
Expected<uint64_t> getAddrEntry(uint32_t Index) const;
/// Return the size of the table header including the length
/// but not including the addresses.
uint8_t getHeaderSize() 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
#endif // LLVM_DEBUGINFO_DWARFDEBUGADDR_H

View File

@ -6,6 +6,7 @@ add_llvm_library(LLVMDebugInfoDWARF
DWARFContext.cpp
DWARFDataExtractor.cpp
DWARFDebugAbbrev.cpp
DWARFDebugAddr.cpp
DWARFDebugArangeSet.cpp
DWARFDebugAranges.cpp
DWARFDebugFrame.cpp

View File

@ -17,6 +17,7 @@
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
@ -249,6 +250,36 @@ static void dumpStringOffsetsSection(
}
}
// Dump the .debug_addr section.
static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
DIDumpOptions DumpOpts, uint16_t Version,
uint8_t AddrSize) {
// TODO: Make this more general: add callback types to Error.h, create
// implementation and make all DWARF classes use them.
static auto WarnCallback = [](Error Warn) {
handleAllErrors(std::move(Warn), [](ErrorInfoBase &Info) {
WithColor::warning() << Info.message() << '\n';
});
};
uint32_t Offset = 0;
while (AddrData.isValidOffset(Offset)) {
DWARFDebugAddrTable AddrTable;
uint32_t TableOffset = Offset;
if (Error Err = AddrTable.extract(AddrData, &Offset, Version,
AddrSize, WarnCallback)) {
WithColor::error() << toString(std::move(Err)) << '\n';
// Keep going after an error, if we can, assuming that the length field
// could be read. If it couldn't, stop reading the section.
if (!AddrTable.hasValidLength())
break;
uint64_t Length = AddrTable.getLength();
Offset = TableOffset + Length;
} else {
AddrTable.dump(OS, DumpOpts);
}
}
}
// Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
static void dumpRnglistsSection(raw_ostream &OS,
DWARFDataExtractor &rnglistData,
@ -455,18 +486,16 @@ void DWARFContext::dump(
}
}
if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
DObj->getAddrSection().Data)) {
DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(),
isLittleEndian(), 0);
dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize());
}
if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
DObj->getRangeSection().Data)) {
// In fact, different compile units may have different address byte
// sizes, but for simplicity we just use the address byte size of the
// last compile unit (there is no easy and fast way to associate address
// range list and the compile unit it describes).
// FIXME: savedAddressByteSize seems sketchy.
uint8_t savedAddressByteSize = 0;
for (const auto &CU : compile_units()) {
savedAddressByteSize = CU->getAddressByteSize();
break;
}
uint8_t savedAddressByteSize = getCUAddrSize();
DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),
isLittleEndian(), savedAddressByteSize);
uint32_t offset = 0;
@ -1584,3 +1613,17 @@ Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) {
RegInfo.reset(TheTarget->createMCRegInfo(TT.str()));
return Error::success();
}
uint8_t DWARFContext::getCUAddrSize() {
// In theory, different compile units may have different address byte
// sizes, but for simplicity we just use the address byte size of the
// last compile unit. In practice the address size field is repeated across
// various DWARF headers (at least in version 5) to make it easier to dump
// them independently, not to enable varying the address size.
uint8_t Addr = 0;
for (const auto &CU : compile_units()) {
Addr = CU->getAddressByteSize();
break;
}
return Addr;
}

View File

@ -0,0 +1,198 @@
//===- DWARFDebugAddr.cpp -------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
using namespace llvm;
void DWARFDebugAddrTable::clear() {
HeaderData = {};
Addrs.clear();
invalidateLength();
}
Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data,
uint32_t *OffsetPtr,
uint16_t Version,
uint8_t AddrSize,
std::function<void(Error)> WarnCallback) {
clear();
HeaderOffset = *OffsetPtr;
// Read and verify the length field.
if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, sizeof(uint32_t)))
return createStringError(errc::invalid_argument,
"section is not large enough to contain a "
".debug_addr table length at offset 0x%"
PRIx32, *OffsetPtr);
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.
Format = dwarf::DwarfFormat::DWARF32;
if (UnitVersion >= 5) {
HeaderData.Length = Data.getU32(OffsetPtr);
if (HeaderData.Length == 0xffffffffu) {
invalidateLength();
return createStringError(errc::not_supported,
"DWARF64 is not supported in .debug_addr at offset 0x%" PRIx32,
HeaderOffset);
}
if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header)) {
uint32_t TmpLength = getLength();
invalidateLength();
return createStringError(errc::invalid_argument,
".debug_addr table at offset 0x%" PRIx32
" has too small length (0x%" PRIx32
") to contain a complete header",
HeaderOffset, TmpLength);
}
uint32_t End = HeaderOffset + getLength();
if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset)) {
uint32_t TmpLength = getLength();
invalidateLength();
return createStringError(errc::invalid_argument,
"section is not large enough to contain a .debug_addr table "
"of length 0x%" PRIx32 " at offset 0x%" PRIx32,
TmpLength, HeaderOffset);
}
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.
// We support DWARF version 5 for now as well as pre-DWARF5
// implementations of .debug_addr table, which doesn't contain a header
// and consists only of a series of addresses.
if (HeaderData.Version > 5) {
return createStringError(errc::not_supported, "version %" PRIu16
" of .debug_addr section at offset 0x%" PRIx32 " is not supported",
HeaderData.Version, HeaderOffset);
}
// FIXME: For now we just treat version mismatch as an error,
// 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,
".debug_addr table at offset 0x%" PRIx32
" 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,
".debug_addr table at offset 0x%" PRIx32
" has unsupported address size %" PRIu8,
HeaderOffset, HeaderData.AddrSize);
if (HeaderData.AddrSize != AddrSize && AddrSize != 0)
return createStringError(errc::invalid_argument,
".debug_addr table at offset 0x%" PRIx32
" has address size %" PRIu8
" which is different from CU address size %" PRIu8,
HeaderOffset, HeaderData.AddrSize, AddrSize);
// TODO: add support for non-zero segment selector size.
if (HeaderData.SegSize != 0)
return createStringError(errc::not_supported,
".debug_addr table at offset 0x%" PRIx32
" has unsupported segment selector size %" PRIu8,
HeaderOffset, HeaderData.SegSize);
if (DataSize % HeaderData.AddrSize != 0) {
invalidateLength();
return createStringError(errc::invalid_argument,
".debug_addr table at offset 0x%" PRIx32
" 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)
if (HeaderData.AddrSize == 4)
Addrs.push_back(Data.getU32(OffsetPtr));
else
Addrs.push_back(Data.getU64(OffsetPtr));
return Error::success();
}
void DWARFDebugAddrTable::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
if (DumpOpts.Verbose)
OS << format("0x%8.8" PRIx32 ": ", HeaderOffset);
OS << format("Addr Section: length = 0x%8.8" PRIx32
", version = 0x%4.4" PRIx16 ", "
"addr_size = 0x%2.2" PRIx8 ", seg_size = 0x%2.2" PRIx8 "\n",
HeaderData.Length, HeaderData.Version, HeaderData.AddrSize,
HeaderData.SegSize);
static const char *Fmt32 = "0x%8.8" PRIx32;
static const char *Fmt64 = "0x%16.16" PRIx64;
std::string AddrFmt = "\n";
std::string AddrFmtVerbose = " => ";
if (HeaderData.AddrSize == 4) {
AddrFmt.append(Fmt32);
AddrFmtVerbose.append(Fmt32);
}
else {
AddrFmt.append(Fmt64);
AddrFmtVerbose.append(Fmt64);
}
if (Addrs.size() > 0) {
OS << "Addrs: [";
for (uint64_t Addr : Addrs) {
OS << format(AddrFmt.c_str(), Addr);
if (DumpOpts.Verbose)
OS << format(AddrFmtVerbose.c_str(),
Addr + HeaderOffset + sizeof(HeaderData));
}
OS << "\n]\n";
}
}
Expected<uint64_t> DWARFDebugAddrTable::getAddrEntry(uint32_t Index) const {
if (Index < Addrs.size())
return Addrs[Index];
return createStringError(errc::invalid_argument,
"Index %" PRIu32 " is out of range of the "
".debug_addr table at offset 0x%" PRIx32,
Index, HeaderOffset);
}
uint32_t DWARFDebugAddrTable::getLength() const {
if (HeaderData.Length == 0)
return 0;
// TODO: DWARF64 support.
return HeaderData.Length + sizeof(uint32_t);
}
uint32_t DWARFDebugAddrTable::getDataSize() const {
if (DataSize != 0)
return DataSize;
if (getLength() == 0)
return 0;
return getLength() - getHeaderSize();
}

View File

@ -0,0 +1,38 @@
# RUN: llvm-mc %s -filetype obj -triple i386-pc-linux -o %t.o
# RUN: llvm-dwarfdump -debug-addr %t.o | FileCheck %s
# 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-NEXT: length = 0x00000004, version = 0x0005, addr_size = 0x04, seg_size = 0x00
# 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 5 # version
.byte 4 # address_size
.byte 0 # segment_selector_size
.long 0x00000000
.long 0x00000001
.section .debug_addr,"",@progbits
.Ldebug_addr1:
.long 4 # unit_length = .short + .byte + .byte
.short 5 # version
.byte 4 # address_size
.byte 0 # segment_selector_size

View File

@ -0,0 +1,29 @@
# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o %t.o
# RUN: llvm-dwarfdump -debug-addr %t.o | FileCheck %s
# CHECK: .debug_addr contents
# CHECK-NEXT: length = 0x00000014, version = 0x0005, addr_size = 0x08, seg_size = 0x00
# CHECK-NEXT: Addrs: [
# CHECK-NEXT: 0x0000000100000000
# CHECK-NEXT: 0x0000000100000001
# 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 8 # Address Size (in bytes)
.long .debug_abbrev # Offset Into Abbrev. Section
.section .debug_addr,"",@progbits
.Ldebug_addr0:
.long 20 # unit_length = .short + .byte + .byte + .quad + .quad
.short 5 # version
.byte 8 # address_size
.byte 0 # segment_selector_size
.quad 0x0000000100000000
.quad 0x0000000100000001

View File

@ -0,0 +1,4 @@
# RUN: llvm-mc %s -filetype obj -triple i386-pc-linux -o - | \
# RUN: llvm-dwarfdump -debug-addr - 2>&1 | FileCheck %s
# CHECK: .debug_addr contents:
# CHECK-NOT: {{.}}

View File

@ -0,0 +1,42 @@
# 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: .debug_addr table at offset 0x0 has address size 8 which is different from CU address size 4
# 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 5 # version
.byte 8 # 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

View File

@ -0,0 +1,18 @@
# 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
# CHECK: .debug_addr contents:
# CHECK-NOT: {{.}}
# ERR: .debug_addr table at offset 0x0 contains data of size 7 which is not a multiple of addr size 4
# ERR-NOT: {{.}}
# data size is not multiple of address_size
.section .debug_addr,"",@progbits
.Ldebug_addr0:
.long 11 # unit_length = .short + .byte + .byte + .long + .long - 1
.short 5 # version
.byte 4 # address_size
.byte 0 # segment_selector_size
.long 0x00000000
.long 0x00000001

View File

@ -0,0 +1,20 @@
# RUN: llvm-mc %s -filetype obj -triple i386-pc-linux -o %t.o
# RUN: llvm-dwarfdump --debug-addr %t.o | FileCheck %s
# CHECK: .debug_addr contents
# CHECK-NEXT: length = 0x00000000, version = 0x0004, addr_size = 0x04, seg_size = 0x00
# CHECK-NEXT: Addrs: [
# CHECK-NEXT: 0x00000000
# CHECK-NEXT: 0x00000001
.section .debug_abbrev,"",@progbits
.byte 1 # Abbreviation Code
.section .debug_info,"",@progbits
.Lcu_begin0:
.long 7 # Length of Unit
.short 4 # DWARF version number
.long .debug_abbrev # Offset Into Abbrev. Section
.byte 4 # Address Size (in bytes)
.section .debug_addr,"",@progbits
.long 0x00000000
.long 0x00000001

View File

@ -0,0 +1,19 @@
# 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
# CHECK: .debug_addr contents:
# CHECK-NOT: {{.}}
# ERR: DWARF64 is not supported in .debug_addr at offset 0x0
# ERR-NOT: {{.}}
# DWARF64 table
.section .debug_addr,"",@progbits
.Ldebug_addr0:
.long 0xffffffff # unit_length DWARF64 mark
.quad 12 # unit_length
.short 5 # version
.byte 3 # address_size
.byte 0 # segment_selector_size
.long 0x00000000
.long 0x00000001

View File

@ -0,0 +1,7 @@
# RUN: llvm-mc %s -filetype obj -triple i386-pc-linux -o - | \
# RUN: llvm-dwarfdump -debug-addr - | FileCheck %s
# CHECK: .debug_addr contents:
# CHECK-NOT: Addr
# CHECK-NOT: error:
.section .debug_addr,"",@progbits

View File

@ -0,0 +1,18 @@
# 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
# CHECK: .debug_addr contents:
# CHECK-NOT: {{.}}
# ERR: unsupported address size 3
# ERR-NOT: {{.}}
# invalid addr size
.section .debug_addr,"",@progbits
.Ldebug_addr0:
.long 12 # unit_length = .short + .byte + .byte + .long + .long
.short 5 # version
.byte 3 # address_size
.byte 0 # segment_selector_size
.long 0x00000000
.long 0x00000001

View File

@ -0,0 +1,17 @@
# 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
# CHECK: .debug_addr contents:
# CHECK-NOT: {{.}}
# ERR: .debug_addr table at offset 0x0 has unsupported segment selector size 1
# ERR-NOT: {{.}}
# non-zero segment_selector_size
# TODO: make this valid
.section .debug_addr,"",@progbits
.Ldebug_addr0:
.long 4 # unit_length = .short + .byte + .byte
.short 5 # version
.byte 4 # address_size
.byte 1 # segment_selector_size

View File

@ -0,0 +1,18 @@
# 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
# CHECK: .debug_addr contents:
# CHECK-NOT: {{.}}
# ERR: .debug_addr table at offset 0x0 has too small length (0x5) to contain a complete header
# ERR-NOT: {{.}}
# too small length value
.section .debug_addr,"",@progbits
.Ldebug_addr0:
.long 1 # unit_length
.short 5 # version
.byte 4 # address_size
.byte 0 # segment_selector_size
.long 0x00000000
.long 0x00000001

View File

@ -0,0 +1,13 @@
# 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
# CHECK: .debug_addr contents:
# CHECK-NOT: {{.}}
# ERR: section is not large enough to contain a .debug_addr table length at offset 0x0
# ERR-NOT: {{.}}
# too small section to contain length field
.section .debug_addr,"",@progbits
.Ldebug_addr0:
.short 1 # unit_length

View File

@ -0,0 +1,16 @@
# 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
# CHECK: .debug_addr contents:
# CHECK-NOT: {{.}}
# ERR: section is not large enough to contain a .debug_addr table of length 0x10 at offset 0x0
# ERR-NOT: {{.}}
# too small section to contain section of given length
.section .debug_addr,"",@progbits
.Ldebug_addr0:
.long 12 # unit_length
.short 5 # version
.byte 4 # address_size
.byte 0 # segment_selector_size

View File

@ -0,0 +1,42 @@
# 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: version 6 of .debug_addr section at offset 0x0 is not supported
# ERR-NOT: {{.}}
# CHECK: .debug_addr contents
# CHECK-NEXT: length = 0x0000000c, version = 0x0005, addr_size = 0x04, seg_size = 0x00
# CHECK-NEXT: Addrs: [
# CHECK-NEXT: 0x00000002
# CHECK-NEXT: 0x00000003
# 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 6 # 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 0x00000002
.long 0x00000003

View File

@ -0,0 +1,42 @@
# 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: .debug_addr 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