DWARFDebugArangeSet.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. //===-- DWARFDebugArangeSet.cpp -------------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
  10. #include "llvm/Support/Format.h"
  11. #include "llvm/Support/raw_ostream.h"
  12. #include <algorithm>
  13. #include <cassert>
  14. using namespace llvm;
  15. void DWARFDebugArangeSet::clear() {
  16. Offset = -1U;
  17. std::memset(&HeaderData, 0, sizeof(Header));
  18. ArangeDescriptors.clear();
  19. }
  20. bool
  21. DWARFDebugArangeSet::extract(DataExtractor data, uint32_t *offset_ptr) {
  22. if (data.isValidOffset(*offset_ptr)) {
  23. ArangeDescriptors.clear();
  24. Offset = *offset_ptr;
  25. // 7.20 Address Range Table
  26. //
  27. // Each set of entries in the table of address ranges contained in
  28. // the .debug_aranges section begins with a header consisting of: a
  29. // 4-byte length containing the length of the set of entries for this
  30. // compilation unit, not including the length field itself; a 2-byte
  31. // version identifier containing the value 2 for DWARF Version 2; a
  32. // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer
  33. // containing the size in bytes of an address (or the offset portion of
  34. // an address for segmented addressing) on the target system; and a
  35. // 1-byte unsigned integer containing the size in bytes of a segment
  36. // descriptor on the target system. This header is followed by a series
  37. // of tuples. Each tuple consists of an address and a length, each in
  38. // the size appropriate for an address on the target architecture.
  39. HeaderData.Length = data.getU32(offset_ptr);
  40. HeaderData.Version = data.getU16(offset_ptr);
  41. HeaderData.CuOffset = data.getU32(offset_ptr);
  42. HeaderData.AddrSize = data.getU8(offset_ptr);
  43. HeaderData.SegSize = data.getU8(offset_ptr);
  44. // Perform basic validation of the header fields.
  45. if (!data.isValidOffsetForDataOfSize(Offset, HeaderData.Length) ||
  46. (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)) {
  47. clear();
  48. return false;
  49. }
  50. // The first tuple following the header in each set begins at an offset
  51. // that is a multiple of the size of a single tuple (that is, twice the
  52. // size of an address). The header is padded, if necessary, to the
  53. // appropriate boundary.
  54. const uint32_t header_size = *offset_ptr - Offset;
  55. const uint32_t tuple_size = HeaderData.AddrSize * 2;
  56. uint32_t first_tuple_offset = 0;
  57. while (first_tuple_offset < header_size)
  58. first_tuple_offset += tuple_size;
  59. *offset_ptr = Offset + first_tuple_offset;
  60. Descriptor arangeDescriptor;
  61. static_assert(sizeof(arangeDescriptor.Address) ==
  62. sizeof(arangeDescriptor.Length),
  63. "Different datatypes for addresses and sizes!");
  64. assert(sizeof(arangeDescriptor.Address) >= HeaderData.AddrSize);
  65. while (data.isValidOffset(*offset_ptr)) {
  66. arangeDescriptor.Address = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
  67. arangeDescriptor.Length = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
  68. // Each set of tuples is terminated by a 0 for the address and 0
  69. // for the length.
  70. if (arangeDescriptor.Address || arangeDescriptor.Length)
  71. ArangeDescriptors.push_back(arangeDescriptor);
  72. else
  73. break; // We are done if we get a zero address and length
  74. }
  75. return !ArangeDescriptors.empty();
  76. }
  77. return false;
  78. }
  79. void DWARFDebugArangeSet::dump(raw_ostream &OS) const {
  80. OS << format("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, ",
  81. HeaderData.Length, HeaderData.Version)
  82. << format("cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n",
  83. HeaderData.CuOffset, HeaderData.AddrSize, HeaderData.SegSize);
  84. const uint32_t hex_width = HeaderData.AddrSize * 2;
  85. for (const auto &Desc : ArangeDescriptors) {
  86. OS << format("[0x%*.*" PRIx64 " -", hex_width, hex_width, Desc.Address)
  87. << format(" 0x%*.*" PRIx64 ")\n",
  88. hex_width, hex_width, Desc.getEndAddress());
  89. }
  90. }