LLVM  10.0.0svn
DWARFListTable.cpp
Go to the documentation of this file.
1 //===- DWARFListTable.cpp ---------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
11 #include "llvm/Support/Errc.h"
12 #include "llvm/Support/Error.h"
13 #include "llvm/Support/Format.h"
15 
16 using namespace llvm;
17 
19  uint64_t *OffsetPtr) {
20  HeaderOffset = *OffsetPtr;
21  // Read and verify the length field.
22  if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, sizeof(uint32_t)))
24  "section is not large enough to contain a "
25  "%s table length at offset 0x%" PRIx64,
26  SectionName.data(), *OffsetPtr);
28  uint8_t OffsetByteSize = 4;
29  HeaderData.Length = Data.getRelocatedValue(4, OffsetPtr);
30  if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64) {
32  OffsetByteSize = 8;
33  HeaderData.Length = Data.getU64(OffsetPtr);
34  } else if (HeaderData.Length >= dwarf::DW_LENGTH_lo_reserved) {
36  "%s table at offset 0x%" PRIx64
37  " has unsupported reserved unit length of value 0x%8.8" PRIx64,
38  SectionName.data(), HeaderOffset, HeaderData.Length);
39  }
40  uint64_t FullLength =
41  HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);
42  assert(FullLength == length());
43  if (FullLength < getHeaderSize(Format))
45  "%s table at offset 0x%" PRIx64
46  " has too small length (0x%" PRIx64
47  ") to contain a complete header",
48  SectionName.data(), HeaderOffset, FullLength);
49  uint64_t End = HeaderOffset + FullLength;
50  if (!Data.isValidOffsetForDataOfSize(HeaderOffset, FullLength))
52  "section is not large enough to contain a %s table "
53  "of length 0x%" PRIx64 " at offset 0x%" PRIx64,
54  SectionName.data(), FullLength, HeaderOffset);
55 
56  HeaderData.Version = Data.getU16(OffsetPtr);
57  HeaderData.AddrSize = Data.getU8(OffsetPtr);
58  HeaderData.SegSize = Data.getU8(OffsetPtr);
59  HeaderData.OffsetEntryCount = Data.getU32(OffsetPtr);
60 
61  // Perform basic validation of the remaining header fields.
62  if (HeaderData.Version != 5)
64  "unrecognised %s table version %" PRIu16
65  " in table at offset 0x%" PRIx64,
66  SectionName.data(), HeaderData.Version, HeaderOffset);
67  if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
69  "%s table at offset 0x%" PRIx64
70  " has unsupported address size %" PRIu8,
71  SectionName.data(), HeaderOffset, HeaderData.AddrSize);
72  if (HeaderData.SegSize != 0)
74  "%s table at offset 0x%" PRIx64
75  " has unsupported segment selector size %" PRIu8,
76  SectionName.data(), HeaderOffset, HeaderData.SegSize);
77  if (End < HeaderOffset + getHeaderSize(Format) +
78  HeaderData.OffsetEntryCount * OffsetByteSize)
80  "%s table at offset 0x%" PRIx64 " has more offset entries (%" PRIu32
81  ") than there is space for",
82  SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount);
83  Data.setAddressSize(HeaderData.AddrSize);
84  for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I)
85  Offsets.push_back(Data.getRelocatedValue(OffsetByteSize, OffsetPtr));
86  return Error::success();
87 }
88 
90  if (DumpOpts.Verbose)
91  OS << format("0x%8.8" PRIx64 ": ", HeaderOffset);
92  OS << format(
93  "%s list header: length = 0x%8.8" PRIx64 ", version = 0x%4.4" PRIx16 ", "
94  "addr_size = 0x%2.2" PRIx8 ", seg_size = 0x%2.2" PRIx8
95  ", offset_entry_count = "
96  "0x%8.8" PRIx32 "\n",
97  ListTypeString.data(), HeaderData.Length, HeaderData.Version,
98  HeaderData.AddrSize, HeaderData.SegSize, HeaderData.OffsetEntryCount);
99 
100  if (HeaderData.OffsetEntryCount > 0) {
101  OS << "offsets: [";
102  for (const auto &Off : Offsets) {
103  OS << format("\n0x%8.8" PRIx64, Off);
104  if (DumpOpts.Verbose)
105  OS << format(" => 0x%8.8" PRIx64,
106  Off + HeaderOffset + getHeaderSize(Format));
107  }
108  OS << "\n]\n";
109  }
110 }
111 
113  if (HeaderData.Length == 0)
114  return 0;
115  return HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);
116 }
uint8_t getU8(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint8_t value from *offset_ptr.
uint16_t getU16(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint16_t value from *offset_ptr.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static uint8_t getHeaderSize(dwarf::DwarfFormat Format)
Return the size of the table header including the length but not including the offsets.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
uint32_t getU32(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint32_t value from *offset_ptr.
uint64_t getRelocatedValue(uint32_t Size, uint64_t *Off, uint64_t *SectionIndex=nullptr, Error *Err=nullptr) const
Extracts a value and applies a relocation to the result if one exists for the given offset...
uint8_t getUnitLengthFieldByteSize(DwarfFormat Format)
Get the byte size of the unit length field depending on the DWARF format.
Definition: Dwarf.h:565
Container for dump options that control which debug information will be dumped.
Definition: DIContext.h:171
Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr)
Extract the table header and the array of offsets.
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
uint64_t length() const
Returns the length of the table, including the length field, or 0 if the length has not been determin...
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
bool isValidOffsetForDataOfSize(uint64_t offset, uint64_t length) const
Test the availability of length bytes of data from offset.
void setAddressSize(uint8_t Size)
Set the address size for this extractor.
Definition: DataExtractor.h:98
This file contains constants used for implementing Dwarf debug support.
#define I(x, y, z)
Definition: MD5.cpp:58
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:136
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
uint64_t getU64(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint64_t value from *offset_ptr.
void dump(raw_ostream &OS, DIDumpOptions DumpOpts={}) const
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1197