1 //===- DWARFDebugAddr.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/DWARFDebugAddr.h" 10 #include "llvm/BinaryFormat/Dwarf.h" 11 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 12 13 using namespace llvm; 14 15 Error DWARFDebugAddrTable::extractAddresses(const DWARFDataExtractor &Data, 16 uint64_t *OffsetPtr, 17 uint64_t EndOffset) { 18 assert(EndOffset >= *OffsetPtr); 19 uint64_t DataSize = EndOffset - *OffsetPtr; 20 assert(Data.isValidOffsetForDataOfSize(*OffsetPtr, DataSize)); 21 if (Error SizeErr = DWARFContext::checkAddressSizeSupported( 22 AddrSize, errc::not_supported, "address table at offset 0x%" PRIx64, 23 Offset)) 24 return SizeErr; 25 if (DataSize % AddrSize != 0) { 26 invalidateLength(); 27 return createStringError(errc::invalid_argument, 28 "address table at offset 0x%" PRIx64 29 " contains data of size 0x%" PRIx64 30 " which is not a multiple of addr size %" PRIu8, 31 Offset, DataSize, AddrSize); 32 } 33 Addrs.clear(); 34 size_t Count = DataSize / AddrSize; 35 Addrs.reserve(Count); 36 while (Count--) 37 Addrs.push_back(Data.getRelocatedValue(AddrSize, OffsetPtr)); 38 return Error::success(); 39 } 40 41 Error DWARFDebugAddrTable::extractV5(const DWARFDataExtractor &Data, 42 uint64_t *OffsetPtr, uint8_t CUAddrSize, 43 std::function<void(Error)> WarnCallback) { 44 Offset = *OffsetPtr; 45 llvm::Error Err = Error::success(); 46 std::tie(Length, Format) = Data.getInitialLength(OffsetPtr, &Err); 47 if (Err) { 48 invalidateLength(); 49 return createStringError(errc::invalid_argument, 50 "parsing address table at offset 0x%" PRIx64 51 ": %s", 52 Offset, toString(std::move(Err)).c_str()); 53 } 54 55 if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, Length)) { 56 uint64_t DiagnosticLength = Length; 57 invalidateLength(); 58 return createStringError( 59 errc::invalid_argument, 60 "section is not large enough to contain an address table " 61 "at offset 0x%" PRIx64 " with a unit_length value of 0x%" PRIx64, 62 Offset, DiagnosticLength); 63 } 64 uint64_t EndOffset = *OffsetPtr + Length; 65 // Ensure that we can read the remaining header fields. 66 if (Length < 4) { 67 uint64_t DiagnosticLength = Length; 68 invalidateLength(); 69 return createStringError( 70 errc::invalid_argument, 71 "address table at offset 0x%" PRIx64 72 " has a unit_length value of 0x%" PRIx64 73 ", which is too small to contain a complete header", 74 Offset, DiagnosticLength); 75 } 76 77 Version = Data.getU16(OffsetPtr); 78 AddrSize = Data.getU8(OffsetPtr); 79 SegSize = Data.getU8(OffsetPtr); 80 81 // Perform a basic validation of the header fields. 82 if (Version != 5) 83 return createStringError(errc::not_supported, 84 "address table at offset 0x%" PRIx64 85 " has unsupported version %" PRIu16, 86 Offset, Version); 87 // TODO: add support for non-zero segment selector size. 88 if (SegSize != 0) 89 return createStringError(errc::not_supported, 90 "address table at offset 0x%" PRIx64 91 " has unsupported segment selector size %" PRIu8, 92 Offset, SegSize); 93 94 if (Error Err = extractAddresses(Data, OffsetPtr, EndOffset)) 95 return Err; 96 if (CUAddrSize && AddrSize != CUAddrSize) { 97 WarnCallback(createStringError( 98 errc::invalid_argument, 99 "address table at offset 0x%" PRIx64 " has address size %" PRIu8 100 " which is different from CU address size %" PRIu8, 101 Offset, AddrSize, CUAddrSize)); 102 } 103 return Error::success(); 104 } 105 106 Error DWARFDebugAddrTable::extractPreStandard(const DWARFDataExtractor &Data, 107 uint64_t *OffsetPtr, 108 uint16_t CUVersion, 109 uint8_t CUAddrSize) { 110 assert(CUVersion > 0 && CUVersion < 5); 111 112 Offset = *OffsetPtr; 113 Length = 0; 114 Version = CUVersion; 115 AddrSize = CUAddrSize; 116 SegSize = 0; 117 118 return extractAddresses(Data, OffsetPtr, Data.size()); 119 } 120 121 Error DWARFDebugAddrTable::extract(const DWARFDataExtractor &Data, 122 uint64_t *OffsetPtr, 123 uint16_t CUVersion, 124 uint8_t CUAddrSize, 125 std::function<void(Error)> WarnCallback) { 126 if (CUVersion > 0 && CUVersion < 5) 127 return extractPreStandard(Data, OffsetPtr, CUVersion, CUAddrSize); 128 if (CUVersion == 0) 129 WarnCallback(createStringError(errc::invalid_argument, 130 "DWARF version is not defined in CU," 131 " assuming version 5")); 132 return extractV5(Data, OffsetPtr, CUAddrSize, WarnCallback); 133 } 134 135 void DWARFDebugAddrTable::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { 136 if (DumpOpts.Verbose) 137 OS << format("0x%8.8" PRIx64 ": ", Offset); 138 if (Length) { 139 int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format); 140 OS << "Address table header: " 141 << format("length = 0x%0*" PRIx64, OffsetDumpWidth, Length) 142 << ", format = " << dwarf::FormatString(Format) 143 << format(", version = 0x%4.4" PRIx16, Version) 144 << format(", addr_size = 0x%2.2" PRIx8, AddrSize) 145 << format(", seg_size = 0x%2.2" PRIx8, SegSize) << "\n"; 146 } 147 148 if (Addrs.size() > 0) { 149 const char *AddrFmt; 150 switch (AddrSize) { 151 case 2: 152 AddrFmt = "0x%4.4" PRIx64 "\n"; 153 break; 154 case 4: 155 AddrFmt = "0x%8.8" PRIx64 "\n"; 156 break; 157 case 8: 158 AddrFmt = "0x%16.16" PRIx64 "\n"; 159 break; 160 default: 161 llvm_unreachable("unsupported address size"); 162 } 163 OS << "Addrs: [\n"; 164 for (uint64_t Addr : Addrs) 165 OS << format(AddrFmt, Addr); 166 OS << "]\n"; 167 } 168 } 169 170 Expected<uint64_t> DWARFDebugAddrTable::getAddrEntry(uint32_t Index) const { 171 if (Index < Addrs.size()) 172 return Addrs[Index]; 173 return createStringError(errc::invalid_argument, 174 "Index %" PRIu32 " is out of range of the " 175 "address table at offset 0x%" PRIx64, 176 Index, Offset); 177 } 178 179 Optional<uint64_t> DWARFDebugAddrTable::getFullLength() const { 180 if (Length == 0) 181 return None; 182 return Length + dwarf::getUnitLengthFieldByteSize(Format); 183 } 184 185