1 //===-llvm/unittest/DebugInfo/DWARFDieManualExtractTest.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 "DwarfGenerator.h" 10 #include "DwarfUtils.h" 11 #include "llvm/BinaryFormat/Dwarf.h" 12 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 13 #include "llvm/ObjectYAML/DWARFEmitter.h" 14 #include "llvm/Testing/Support/Error.h" 15 #include "gtest/gtest.h" 16 17 using namespace llvm; 18 using namespace llvm::dwarf; 19 using namespace utils; 20 21 namespace { 22 23 TEST(DWARFDie, manualExtractDump) { 24 typedef uint32_t AddrType; 25 uint16_t Version = 4; 26 Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType)); 27 if (!isConfigurationSupported(Triple)) 28 return; 29 30 auto ExpectedDG = dwarfgen::Generator::create(Triple, Version); 31 ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); 32 dwarfgen::Generator *DG = ExpectedDG.get().get(); 33 dwarfgen::CompileUnit &DGCU = DG->addCompileUnit(); 34 dwarfgen::DIE CUDie = DGCU.getUnitDIE(); 35 36 CUDie.addAttribute(DW_AT_name, DW_FORM_strp, "/tmp/main.c"); 37 CUDie.addAttribute(DW_AT_language, DW_FORM_data2, DW_LANG_C); 38 39 dwarfgen::DIE SubprogramDie = CUDie.addChild(DW_TAG_subprogram); 40 SubprogramDie.addAttribute(DW_AT_name, DW_FORM_strp, "main"); 41 SubprogramDie.addAttribute(DW_AT_low_pc, DW_FORM_addr, 0x1000U); 42 SubprogramDie.addAttribute(DW_AT_high_pc, DW_FORM_addr, 0x2000U); 43 44 StringRef FileBytes = DG->generate(); 45 MemoryBufferRef FileBuffer(FileBytes, "dwarf"); 46 auto Obj = object::ObjectFile::createObjectFile(FileBuffer); 47 EXPECT_TRUE((bool)Obj); 48 std::unique_ptr<DWARFContext> Ctx = DWARFContext::create(**Obj); 49 50 DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0); 51 ASSERT_NE(nullptr, CU); 52 // Manually extracting DWARF DIE. 53 uint64_t DIEOffset = CU->getOffset() + CU->getHeaderSize(); 54 uint64_t NextCUOffset = CU->getNextUnitOffset(); 55 DWARFDebugInfoEntry DieInfo; 56 DWARFDataExtractor DebugInfoData = CU->getDebugInfoExtractor(); 57 ASSERT_TRUE(DieInfo.extractFast(*CU, &DIEOffset, DebugInfoData, NextCUOffset, 58 UINT32_MAX)); 59 DWARFDie Die(CU, &DieInfo); 60 ASSERT_TRUE(Die.isValid()); 61 ASSERT_TRUE(Die.hasChildren()); 62 // Since we have extracted manually DieArray is empty. 63 // Dump function should respect the default flags and print just current DIE, 64 // and not explore children. 65 SmallString<512> Output; 66 raw_svector_ostream OS(Output); 67 Die.dump(OS); 68 constexpr size_t NumOfLines = 3; 69 SmallVector<StringRef, NumOfLines> Strings; 70 SmallVector<StringRef, NumOfLines> ValidStrings = { 71 "0x0000000b: DW_TAG_compile_unit", 72 " DW_AT_name (\"/tmp/main.c\")", 73 " DW_AT_language (DW_LANG_C)"}; 74 Output.str().split(Strings, '\n', -1, false); 75 ASSERT_EQ(Strings.size(), NumOfLines); 76 for (size_t I = 0; I < NumOfLines; ++I) 77 EXPECT_EQ(ValidStrings[I], Strings[I]); 78 } 79 80 } // end anonymous namespace 81