]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / DebugInfo / DWARF / DWARFListTable.cpp
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
9 #include "llvm/DebugInfo/DWARF/DWARFListTable.h"
10 #include "llvm/BinaryFormat/Dwarf.h"
11 #include "llvm/Support/Errc.h"
12 #include "llvm/Support/Error.h"
13 #include "llvm/Support/Format.h"
14 #include "llvm/Support/raw_ostream.h"
15
16 using namespace llvm;
17
18 Error DWARFListTableHeader::extract(DWARFDataExtractor Data,
19                                     uint32_t *OffsetPtr) {
20   HeaderOffset = *OffsetPtr;
21   // Read and verify the length field.
22   if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, sizeof(uint32_t)))
23     return createStringError(errc::invalid_argument,
24                        "section is not large enough to contain a "
25                        "%s table length at offset 0x%" PRIx32,
26                        SectionName.data(), *OffsetPtr);
27   // TODO: Add support for DWARF64.
28   HeaderData.Length = Data.getRelocatedValue(4, OffsetPtr);
29   if (HeaderData.Length == 0xffffffffu)
30     return createStringError(errc::not_supported,
31                        "DWARF64 is not supported in %s at offset 0x%" PRIx32,
32                        SectionName.data(), HeaderOffset);
33   Format = dwarf::DwarfFormat::DWARF32;
34   if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header))
35     return createStringError(errc::invalid_argument,
36                        "%s table at offset 0x%" PRIx32
37                        " has too small length (0x%" PRIx32
38                        ") to contain a complete header",
39                        SectionName.data(), HeaderOffset, length());
40   uint32_t End = HeaderOffset + length();
41   if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset))
42     return createStringError(errc::invalid_argument,
43                        "section is not large enough to contain a %s table "
44                        "of length 0x%" PRIx32 " at offset 0x%" PRIx32,
45                        SectionName.data(), length(), HeaderOffset);
46
47   HeaderData.Version = Data.getU16(OffsetPtr);
48   HeaderData.AddrSize = Data.getU8(OffsetPtr);
49   HeaderData.SegSize = Data.getU8(OffsetPtr);
50   HeaderData.OffsetEntryCount = Data.getU32(OffsetPtr);
51
52   // Perform basic validation of the remaining header fields.
53   if (HeaderData.Version != 5)
54     return createStringError(errc::invalid_argument,
55                        "unrecognised %s table version %" PRIu16
56                        " in table at offset 0x%" PRIx32,
57                        SectionName.data(), HeaderData.Version, HeaderOffset);
58   if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
59     return createStringError(errc::not_supported,
60                        "%s table at offset 0x%" PRIx32
61                        " has unsupported address size %" PRIu8,
62                        SectionName.data(), HeaderOffset, HeaderData.AddrSize);
63   if (HeaderData.SegSize != 0)
64     return createStringError(errc::not_supported,
65                        "%s table at offset 0x%" PRIx32
66                        " has unsupported segment selector size %" PRIu8,
67                        SectionName.data(), HeaderOffset, HeaderData.SegSize);
68   if (End < HeaderOffset + sizeof(HeaderData) +
69                 HeaderData.OffsetEntryCount * sizeof(uint32_t))
70     return createStringError(errc::invalid_argument,
71         "%s table at offset 0x%" PRIx32 " has more offset entries (%" PRIu32
72         ") than there is space for",
73         SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount);
74   Data.setAddressSize(HeaderData.AddrSize);
75   for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I)
76     Offsets.push_back(Data.getRelocatedValue(4, OffsetPtr));
77   return Error::success();
78 }
79
80 void DWARFListTableHeader::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
81   if (DumpOpts.Verbose)
82     OS << format("0x%8.8" PRIx32 ": ", HeaderOffset);
83   OS << format(
84       "%s list header: length = 0x%8.8" PRIx32 ", version = 0x%4.4" PRIx16 ", "
85       "addr_size = 0x%2.2" PRIx8 ", seg_size = 0x%2.2" PRIx8
86       ", offset_entry_count = "
87       "0x%8.8" PRIx32 "\n",
88       ListTypeString.data(), HeaderData.Length, HeaderData.Version,
89       HeaderData.AddrSize, HeaderData.SegSize, HeaderData.OffsetEntryCount);
90
91   if (HeaderData.OffsetEntryCount > 0) {
92     OS << "offsets: [";
93     for (const auto &Off : Offsets) {
94       OS << format("\n0x%8.8" PRIx32, Off);
95       if (DumpOpts.Verbose)
96         OS << format(" => 0x%8.8" PRIx32,
97                      Off + HeaderOffset + sizeof(HeaderData));
98     }
99     OS << "\n]\n";
100   }
101 }
102
103 uint32_t DWARFListTableHeader::length() const {
104   if (HeaderData.Length == 0)
105     return 0;
106   // TODO: DWARF64 support.
107   return HeaderData.Length + sizeof(uint32_t);
108 }