llvm.org GIT mirror llvm / a6d921e
Recommit "[DWARFv5] Dump an MD5 checksum in the line-table header." Adds missing support for DW_FORM_data16. Update of r320852/r320886, fixing the unittest again, this time use a raw char string for the test data. Differential Revision: https://reviews.llvm.org/D41090 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321011 91177308-0d34-0410-b5e6-96231b3b80d8 Paul Robinson 2 years ago
7 changed file(s) with 87 addition(s) and 27 deletion(s). Raw diff Collapse all Expand all
1414 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
1515 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
1616 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
17 #include "llvm/Support/MD5.h"
1718 #include
1819 #include
1920 #include
3334 uint64_t DirIdx = 0;
3435 uint64_t ModTime = 0;
3536 uint64_t Length = 0;
37 MD5::MD5Result Checksum;
3638 };
3739
3840 struct Prologue {
4547 /// parameters affect interpretation of forms (used in the directory and
4648 /// file tables starting with v5).
4749 DWARFFormParams FormParams;
48 /// In v5, size in bytes of a segment selector.
49 uint8_t SegSelectorSize;
5050 /// The number of bytes following the prologue_length field to the beginning
5151 /// of the first byte of the statement program itself.
5252 uint64_t PrologueLength;
53 /// In v5, size in bytes of a segment selector.
54 uint8_t SegSelectorSize;
5355 /// The size in bytes of the smallest target machine instruction. Statement
5456 /// program opcodes that alter the address register first multiply their
5557 /// operands by this value.
6567 uint8_t LineRange;
6668 /// The number assigned to the first special opcode.
6769 uint8_t OpcodeBase;
70 /// For v5, whether filename entries provide an MD5 checksum.
71 bool HasMD5;
6872 std::vector StandardOpcodeLengths;
6973 std::vector IncludeDirectories;
7074 std::vector FileNames;
776776 case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break;
777777 case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break;
778778 case dwarf::DW_FORM_block: Asm->EmitULEB128(Size); break;
779 case dwarf::DW_FORM_data16: break;
779780 }
780781
781782 for (const auto &V : values())
790791 case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
791792 case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
792793 case dwarf::DW_FORM_block: return Size + getULEB128Size(Size);
794 case dwarf::DW_FORM_data16: return 16;
793795 default: llvm_unreachable("Improper form for block");
794796 }
795797 }
4747 MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
4848 OpcodeBase = 0;
4949 FormParams = DWARFFormParams({0, 0, DWARF32});
50 HasMD5 = false;
5051 StandardOpcodeLengths.clear();
5152 IncludeDirectories.clear();
5253 FileNames.clear();
7778 << IncludeDirectories[I] << "'\n";
7879
7980 if (!FileNames.empty()) {
80 OS << " Dir Mod Time File Len File Name\n"
81 << " ---- ---------- ---------- -----------"
82 "----------------\n";
81 if (HasMD5)
82 OS << " Dir MD5 Checksum File Name\n"
83 << " ---- -------------------------------- -----------"
84 "---------------\n";
85 else
86 OS << " Dir Mod Time File Len File Name\n"
87 << " ---- ---------- ---------- -----------"
88 "----------------\n";
8389 for (uint32_t I = 0; I != FileNames.size(); ++I) {
8490 const FileNameEntry &FileEntry = FileNames[I];
85 OS << format("file_names[%3u] %4" PRIu64 " ", I + 1, FileEntry.DirIdx)
86 << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ", FileEntry.ModTime,
87 FileEntry.Length)
88 << FileEntry.Name << '\n';
91 OS << format("file_names[%3u] %4" PRIu64 " ", I + 1, FileEntry.DirIdx);
92 if (HasMD5)
93 OS << FileEntry.Checksum.digest();
94 else
95 OS << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64, FileEntry.ModTime,
96 FileEntry.Length);
97 OS << ' ' << FileEntry.Name << '\n';
8998 }
9099 }
91100 }
121130 // ran off the end of the prologue.
122131 static ContentDescriptors
123132 parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr,
124 uint64_t EndPrologueOffset) {
133 uint64_t EndPrologueOffset, bool *HasMD5) {
125134 ContentDescriptors Descriptors;
126135 int FormatCount = DebugLineData.getU8(OffsetPtr);
127136 bool HasPath = false;
134143 Descriptor.Form = dwarf::Form(DebugLineData.getULEB128(OffsetPtr));
135144 if (Descriptor.Type == dwarf::DW_LNCT_path)
136145 HasPath = true;
146 else if (Descriptor.Type == dwarf::DW_LNCT_MD5 && HasMD5)
147 *HasMD5 = true;
137148 Descriptors.push_back(Descriptor);
138149 }
139150 return HasPath ? Descriptors : ContentDescriptors();
143154 parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
144155 uint32_t *OffsetPtr, uint64_t EndPrologueOffset,
145156 const DWARFFormParams &FormParams, const DWARFUnit *U,
146 std::vector &IncludeDirectories,
157 bool &HasMD5, std::vector &IncludeDirectories,
147158 std::vector &FileNames) {
148159 // Get the directory entry description.
149160 ContentDescriptors DirDescriptors =
150 parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset);
161 parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset, nullptr);
151162 if (DirDescriptors.empty())
152163 return false;
153164
173184
174185 // Get the file entry description.
175186 ContentDescriptors FileDescriptors =
176 parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset);
187 parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset, &HasMD5);
177188 if (FileDescriptors.empty())
178189 return false;
179190
200211 case DW_LNCT_size:
201212 FileEntry.Length = Value.getAsUnsignedConstant().getValue();
202213 break;
203 // FIXME: Add MD5
214 case DW_LNCT_MD5:
215 assert(Value.getAsBlock().getValue().size() == 16);
216 std::uninitialized_copy_n(Value.getAsBlock().getValue().begin(), 16,
217 FileEntry.Checksum.Bytes.begin());
218 break;
204219 default:
205220 break;
206221 }
252267
253268 if (getVersion() >= 5) {
254269 if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
255 getFormParams(), U, IncludeDirectories,
270 getFormParams(), U, HasMD5, IncludeDirectories,
256271 FileNames)) {
257272 fprintf(stderr,
258273 "warning: parsing line table prologue at 0x%8.8" PRIx64
185185 case DW_FORM_data2:
186186 case DW_FORM_data4:
187187 case DW_FORM_data8:
188 case DW_FORM_data16:
188189 case DW_FORM_flag:
189190 case DW_FORM_ref1:
190191 case DW_FORM_ref2:
338339 case DW_FORM_ref_sup8:
339340 Value.uval = Data.getU64(OffsetPtr);
340341 break;
342 case DW_FORM_data16:
343 // Treat this like a 16-byte block.
344 Value.uval = 16;
345 IsBlock = true;
346 break;
341347 case DW_FORM_sdata:
342348 Value.sval = Data.getSLEB128(OffsetPtr);
343349 break;
430436 break;
431437 case DW_FORM_data8:
432438 OS << format("0x%016" PRIx64, UValue);
439 break;
440 case DW_FORM_data16:
441 OS << format_bytes(ArrayRef(Value.data, 16), None, 16, 16);
433442 break;
434443 case DW_FORM_string:
435444 OS << '"';
650659 }
651660
652661 Optional> DWARFFormValue::getAsBlock() const {
653 if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc))
662 if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) &&
663 Form != DW_FORM_data16)
654664 return None;
655665 return makeArrayRef(Value.data, Value.uval);
656666 }
297297 .long str_LT_5a
298298 .long str_LT_5b
299299 # File table format
300 .byte 4 # Four elements per file entry
300 .byte 3 # Three elements per file entry
301301 .byte 1 # DW_LNCT_path
302302 .byte 0x08 # DW_FORM_string
303303 .byte 2 # DW_LNCT_directory_index
304304 .byte 0x0b # DW_FORM_data1
305 .byte 3 # DW_LNCT_timestamp
306 .byte 0x0f # DW_FORM_udata
307 .byte 4 # DW_LNCT_size
308 .byte 0x0f # DW_FORM_udata
305 .byte 5 # DW_LNCT_MD5
306 .byte 0x1e # DW_FORM_data16
309307 # File table entries
310308 .byte 2 # Two files
311309 .asciz "File5a"
312310 .byte 1
313 .byte 0x51
314 .byte 0x52
311 .quad 0x7766554433221100
312 .quad 0xffeeddccbbaa9988
315313 .asciz "File5b"
316314 .byte 2
317 .byte 0x53
318 .byte 0x54
315 .quad 0x8899aabbccddeeff
316 .quad 0x0011223344556677
319317 LH_5_header_end:
320318 # Line number program, which is empty.
321319 LH_5_end:
328326 # CHECK: include_directories[ 1] = 'Directory5a'
329327 # CHECK: include_directories[ 2] = 'Directory5b'
330328 # CHECK-NOT: include_directories
331 # CHECK: file_names[ 1] 1 0x00000051 0x00000052 File5a{{$}}
332 # CHECK: file_names[ 2] 2 0x00000053 0x00000054 File5b{{$}}
329 # CHECK: MD5 Checksum
330 # CHECK: file_names[ 1] 1 00112233445566778899aabbccddeeff File5a{{$}}
331 # CHECK: file_names[ 2] 2 ffeeddccbbaa99887766554433221100 File5b{{$}}
333332 # CHECK-NOT: file_names
334333
335334 .section .debug_line.dwo,"",@progbits
8181 const uint32_t Data4 = 0x6789abcdU;
8282 const uint64_t Data8 = 0x0011223344556677ULL;
8383 const uint64_t Data8_2 = 0xAABBCCDDEEFF0011ULL;
84 const uint8_t Data16[16] = {1, 2, 3, 4, 5, 6, 7, 8,
85 9, 10, 11, 12, 13, 14, 15, 16};
8486 const int64_t SData = INT64_MIN;
8587 const int64_t ICSData = INT64_MAX; // DW_FORM_implicit_const SData
8688 const uint64_t UData[] = {UINT64_MAX - 1, UINT64_MAX - 2, UINT64_MAX - 3,
118120
119121 const auto Attr_DW_FORM_block4 = static_cast(Attr++);
120122 CUDie.addAttribute(Attr_DW_FORM_block4, DW_FORM_block4, BlockData, BlockSize);
123
124 // We handle data16 as a block form.
125 const auto Attr_DW_FORM_data16 = static_cast(Attr++);
126 if (Version >= 5)
127 CUDie.addAttribute(Attr_DW_FORM_data16, DW_FORM_data16, Data16, 16);
121128
122129 //----------------------------------------------------------------------
123130 // Test data forms
274281 ExtractedBlockData = BlockDataOpt.getValue();
275282 EXPECT_EQ(ExtractedBlockData.size(), BlockSize);
276283 EXPECT_TRUE(memcmp(ExtractedBlockData.data(), BlockData, BlockSize) == 0);
284
285 // Data16 is handled like a block.
286 if (Version >= 5) {
287 FormValue = DieDG.find(Attr_DW_FORM_data16);
288 EXPECT_TRUE((bool)FormValue);
289 BlockDataOpt = FormValue->getAsBlock();
290 EXPECT_TRUE(BlockDataOpt.hasValue());
291 ExtractedBlockData = BlockDataOpt.getValue();
292 EXPECT_EQ(ExtractedBlockData.size(), 16u);
293 EXPECT_TRUE(memcmp(ExtractedBlockData.data(), Data16, 16) == 0);
294 }
277295
278296 //----------------------------------------------------------------------
279297 // Test data forms
159159 EXPECT_EQ(LEBMax.getAsSignedConstant().getValue(), LLONG_MAX);
160160 EXPECT_EQ(LEB1.getAsSignedConstant().getValue(), -42);
161161 EXPECT_EQ(LEB2.getAsSignedConstant().getValue(), 42);
162
163 // Data16 is a little tricky.
164 char Cksum[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
165 DWARFFormValue Data16(DW_FORM_data16);
166 DWARFDataExtractor DE16(StringRef(Cksum, 16), sys::IsLittleEndianHost,
167 sizeof(void *));
168 uint32_t Offset = 0;
169 Data16.extractValue(DE16, &Offset, {0, 0, dwarf::DwarfFormat::DWARF32});
170 SmallString<32> Str;
171 raw_svector_ostream Res(Str);
172 Data16.dump(Res, DIDumpOptions());
173 EXPECT_EQ(memcmp(Str.data(), "000102030405060708090a0b0c0d0e0f", 32), 0);
162174 }
163175
164176 } // end anonymous namespace