From eceb5b99777ba944a0ae3748a0371e9a3aa94d56 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Mon, 27 Aug 2012 07:17:47 +0000 Subject: Add basic support for .debug_ranges section to LLVM's DebugInfo library. This section (introduced in DWARF-3) is used to define instruction address ranges for functions that are not contiguous and can't be described by low_pc/high_pc attributes (this is the usual case for inlined subroutines). The patch is the first step to support fetching complete inlining info from DWARF. Reviewed by Benjamin Kramer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162657 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/DebugInfo/DWARFDebugRangeList.cpp | 58 +++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 lib/DebugInfo/DWARFDebugRangeList.cpp (limited to 'lib/DebugInfo/DWARFDebugRangeList.cpp') diff --git a/lib/DebugInfo/DWARFDebugRangeList.cpp b/lib/DebugInfo/DWARFDebugRangeList.cpp new file mode 100644 index 0000000..10f51b4 --- /dev/null +++ b/lib/DebugInfo/DWARFDebugRangeList.cpp @@ -0,0 +1,58 @@ +//===-- DWARFDebugRangesList.cpp ------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFDebugRangeList.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +void DWARFDebugRangeList::clear() { + Offset = -1U; + AddressSize = 0; + Entries.clear(); +} + +bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr) { + clear(); + if (!data.isValidOffset(*offset_ptr)) + return false; + AddressSize = data.getAddressSize(); + if (AddressSize != 4 && AddressSize != 8) + return false; + Offset = *offset_ptr; + while (true) { + RangeListEntry entry; + uint32_t prev_offset = *offset_ptr; + entry.StartAddress = data.getAddress(offset_ptr); + entry.EndAddress = data.getAddress(offset_ptr); + // Check that both values were extracted correctly. + if (*offset_ptr != prev_offset + 2 * AddressSize) { + clear(); + return false; + } + // The end of any given range list is marked by an end of list entry, + // which consists of a 0 for the beginning address offset + // and a 0 for the ending address offset. + if (entry.StartAddress == 0 && entry.EndAddress == 0) + break; + Entries.push_back(entry); + } + return true; +} + +void DWARFDebugRangeList::dump(raw_ostream &OS) const { + for (int i = 0, n = Entries.size(); i != n; ++i) { + const char *format_str = (AddressSize == 4) ? "%08x %08x %08x\n" + : "%08x %016x %016x\n"; + OS << format(format_str, Offset, Entries[i].StartAddress, + Entries[i].EndAddress); + } + OS << format("%08x \n", Offset); +} -- cgit v1.1 From 83e2546ad3fd75dca35dc3cdbf8f0d085d57e189 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 27 Aug 2012 10:10:10 +0000 Subject: DWARFDebugRangeList.cpp: Use PRIx64 for uint64_t as format string. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162665 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/DebugInfo/DWARFDebugRangeList.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/DebugInfo/DWARFDebugRangeList.cpp') diff --git a/lib/DebugInfo/DWARFDebugRangeList.cpp b/lib/DebugInfo/DWARFDebugRangeList.cpp index 10f51b4..8012e30 100644 --- a/lib/DebugInfo/DWARFDebugRangeList.cpp +++ b/lib/DebugInfo/DWARFDebugRangeList.cpp @@ -49,8 +49,9 @@ bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr) { void DWARFDebugRangeList::dump(raw_ostream &OS) const { for (int i = 0, n = Entries.size(); i != n; ++i) { - const char *format_str = (AddressSize == 4) ? "%08x %08x %08x\n" - : "%08x %016x %016x\n"; + const char *format_str = (AddressSize == 4 + ? "%08x %08"PRIx64" %08"PRIx64"\n" + : "%08x %016"PRIx64" %016"PRIx64"\n"); OS << format(format_str, Offset, Entries[i].StartAddress, Entries[i].EndAddress); } -- cgit v1.1 From e1630e01dee7f131eda6c1ddac4b6776fa1b31f4 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Mon, 27 Aug 2012 22:53:35 +0000 Subject: Fix compile error when building with C++11 - clang thinks that PRIx64 is a user-defined suffix or something git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162704 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/DebugInfo/DWARFDebugRangeList.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/DebugInfo/DWARFDebugRangeList.cpp') diff --git a/lib/DebugInfo/DWARFDebugRangeList.cpp b/lib/DebugInfo/DWARFDebugRangeList.cpp index 8012e30..fa15bb0 100644 --- a/lib/DebugInfo/DWARFDebugRangeList.cpp +++ b/lib/DebugInfo/DWARFDebugRangeList.cpp @@ -50,8 +50,8 @@ bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr) { void DWARFDebugRangeList::dump(raw_ostream &OS) const { for (int i = 0, n = Entries.size(); i != n; ++i) { const char *format_str = (AddressSize == 4 - ? "%08x %08"PRIx64" %08"PRIx64"\n" - : "%08x %016"PRIx64" %016"PRIx64"\n"); + ? "%08x %08" PRIx64 " %08" PRIx64 "\n" + : "%08x %016" PRIx64 " %016" PRIx64 "\n"); OS << format(format_str, Offset, Entries[i].StartAddress, Entries[i].EndAddress); } -- cgit v1.1 From 5eae90d727c64ca5b4b43b110521b38dcd9f0de6 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Tue, 4 Sep 2012 08:12:33 +0000 Subject: Add support for fetching inlining context (stack of source code locations) by instruction address from DWARF. Add --inlining flag to llvm-dwarfdump to demonstrate and test this functionality, so that "llvm-dwarfdump --inlining --address=0x..." now works much like "addr2line -i 0x...", provided that the binary has debug info (Clang's -gline-tables-only *is* enough). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163128 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/DebugInfo/DWARFDebugRangeList.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'lib/DebugInfo/DWARFDebugRangeList.cpp') diff --git a/lib/DebugInfo/DWARFDebugRangeList.cpp b/lib/DebugInfo/DWARFDebugRangeList.cpp index fa15bb0..1806bee 100644 --- a/lib/DebugInfo/DWARFDebugRangeList.cpp +++ b/lib/DebugInfo/DWARFDebugRangeList.cpp @@ -37,10 +37,7 @@ bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr) { clear(); return false; } - // The end of any given range list is marked by an end of list entry, - // which consists of a 0 for the beginning address offset - // and a 0 for the ending address offset. - if (entry.StartAddress == 0 && entry.EndAddress == 0) + if (entry.isEndOfListEntry()) break; Entries.push_back(entry); } @@ -57,3 +54,14 @@ void DWARFDebugRangeList::dump(raw_ostream &OS) const { } OS << format("%08x \n", Offset); } + +bool DWARFDebugRangeList::containsAddress(uint64_t BaseAddress, + uint64_t Address) const { + for (int i = 0, n = Entries.size(); i != n; ++i) { + if (Entries[i].isBaseAddressSelectionEntry(AddressSize)) + BaseAddress = Entries[i].EndAddress; + else if (Entries[i].containsAddress(BaseAddress, Address)) + return true; + } + return false; +} -- cgit v1.1