brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.8 KiB · 8c23b47 Raw
363 lines · cpp
1//===- llvm/unittest/DebugInfo/LogicalView/DWARFGeneratedTest.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-exception6//7//===----------------------------------------------------------------------===//8 9#include "../DWARF/DwarfGenerator.h"10#include "../DWARF/DwarfUtils.h"11#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"12#include "llvm/DebugInfo/DWARF/DWARFContext.h"13#include "llvm/DebugInfo/LogicalView/Core/LVReader.h"14#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"15#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"16#include "llvm/DebugInfo/LogicalView/Core/LVType.h"17#include "llvm/DebugInfo/LogicalView/LVReaderHandler.h"18#include "llvm/MC/TargetRegistry.h"19#include "llvm/Support/COM.h"20#include "llvm/Support/InitLLVM.h"21#include "llvm/Support/ScopedPrinter.h"22#include "llvm/Support/TargetSelect.h"23#include "llvm/Support/ToolOutputFile.h"24#include "llvm/Testing/Support/Error.h"25#include "llvm/Testing/Support/SupportHelpers.h"26 27#include "gtest/gtest.h"28 29using namespace llvm;30using namespace llvm::logicalview;31using namespace llvm::dwarf;32using namespace llvm::dwarf::utils;33 34namespace {35 36// Helper function to get the first compile unit.37LVScopeCompileUnit *getFirstCompileUnit(LVScopeRoot *Root) {38  if (!Root)39    return nullptr;40 41  const LVScopes *CompileUnits = Root->getScopes();42  if (!CompileUnits)43    return nullptr;44 45  LVScopes::const_iterator Iter = CompileUnits->begin();46  return (Iter != CompileUnits->end())47             ? static_cast<LVScopeCompileUnit *>(*Iter)48             : nullptr;49}50 51// Helper function to create a reader.52std::unique_ptr<LVReader> createReader(LVReaderHandler &ReaderHandler,53                                       SmallString<128> &InputsDir,54                                       StringRef Filename) {55  SmallString<128> ObjectName(InputsDir);56  llvm::sys::path::append(ObjectName, Filename);57 58  Expected<std::unique_ptr<LVReader>> ReaderOrErr =59      ReaderHandler.createReader(std::string(ObjectName));60  EXPECT_THAT_EXPECTED(ReaderOrErr, Succeeded());61  std::unique_ptr<LVReader> Reader = std::move(*ReaderOrErr);62  return Reader;63}64 65// Create a file with generated DWARF.66void generateDebugInfo(StringRef Path, Triple &Triple) {67  uint16_t Version = 5;68  auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);69  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());70  dwarfgen::Generator *DG = ExpectedDG.get().get();71  dwarfgen::CompileUnit &CU = DG->addCompileUnit();72 73  dwarfgen::DIE CUDie = CU.getUnitDIE();74  CUDie.addAttribute(DW_AT_name, DW_FORM_strp, "test.cpp");75  CUDie.addAttribute(DW_AT_language, DW_FORM_data2, DW_LANG_C_plus_plus);76  CUDie.addAttribute(DW_AT_producer, DW_FORM_strp, "dwarfgen::Generator");77 78  dwarfgen::DIE ScopeValueDie = CUDie.addChild(DW_TAG_inlined_subroutine);79  ScopeValueDie.addAttribute(DW_AT_accessibility, DW_FORM_data1, 1);80  ScopeValueDie.addAttribute(DW_AT_inline, DW_FORM_data4, 2);81  ScopeValueDie.addAttribute(DW_AT_virtuality, DW_FORM_data4, 3);82  ScopeValueDie.addAttribute(DW_AT_call_file, DW_FORM_data4, 4);83  ScopeValueDie.addAttribute(DW_AT_call_line, DW_FORM_data4, 5);84  ScopeValueDie.addAttribute(DW_AT_decl_file, DW_FORM_data4, 6);85  ScopeValueDie.addAttribute(DW_AT_decl_line, DW_FORM_data4, 7);86  ScopeValueDie.addAttribute(DW_AT_GNU_discriminator, DW_FORM_data4, 8);87 88  dwarfgen::DIE ScopeNoValueDie = CUDie.addChild(DW_TAG_inlined_subroutine);89  ScopeNoValueDie.addAttribute(DW_AT_accessibility, DW_FORM_sdata, 1);90  ScopeNoValueDie.addAttribute(DW_AT_inline, DW_FORM_sdata, 2);91  ScopeNoValueDie.addAttribute(DW_AT_virtuality, DW_FORM_sdata, 3);92  ScopeNoValueDie.addAttribute(DW_AT_call_file, DW_FORM_sdata, 4);93  ScopeNoValueDie.addAttribute(DW_AT_call_line, DW_FORM_sdata, 5);94  ScopeNoValueDie.addAttribute(DW_AT_decl_file, DW_FORM_sdata, 6);95  ScopeNoValueDie.addAttribute(DW_AT_decl_line, DW_FORM_sdata, 7);96  ScopeNoValueDie.addAttribute(DW_AT_GNU_discriminator, DW_FORM_sdata, 8);97 98  dwarfgen::DIE ScopeImplicitDie = CUDie.addChild(DW_TAG_inlined_subroutine);99  ScopeImplicitDie.addAttribute(DW_AT_accessibility, DW_FORM_implicit_const, 1);100  ScopeImplicitDie.addAttribute(DW_AT_inline, DW_FORM_implicit_const, 2);101  ScopeImplicitDie.addAttribute(DW_AT_virtuality, DW_FORM_implicit_const, 3);102  ScopeImplicitDie.addAttribute(DW_AT_call_file, DW_FORM_implicit_const, 4);103  ScopeImplicitDie.addAttribute(DW_AT_call_line, DW_FORM_implicit_const, 5);104  ScopeImplicitDie.addAttribute(DW_AT_decl_file, DW_FORM_implicit_const, 6);105  ScopeImplicitDie.addAttribute(DW_AT_decl_line, DW_FORM_implicit_const, 7);106  ScopeImplicitDie.addAttribute(DW_AT_GNU_discriminator, DW_FORM_implicit_const,107                                8);108 109  dwarfgen::DIE SymbolValueDie = CUDie.addChild(DW_TAG_variable);110  SymbolValueDie.addAttribute(DW_AT_bit_size, DW_FORM_data1, 1);111 112  dwarfgen::DIE SymbolNoValueDie = CUDie.addChild(DW_TAG_variable);113  SymbolNoValueDie.addAttribute(DW_AT_bit_size, DW_FORM_sdata, 1);114 115  dwarfgen::DIE SymbolImplicitDie = CUDie.addChild(DW_TAG_variable);116  SymbolImplicitDie.addAttribute(DW_AT_bit_size, DW_FORM_implicit_const, 1);117 118  dwarfgen::DIE TypeValueCountDie = CUDie.addChild(DW_TAG_subrange_type);119  TypeValueCountDie.addAttribute(DW_AT_count, DW_FORM_data4, 1);120 121  dwarfgen::DIE TypeNoValueCountDie = CUDie.addChild(DW_TAG_subrange_type);122  TypeNoValueCountDie.addAttribute(DW_AT_count, DW_FORM_sdata, 1);123 124  dwarfgen::DIE TypeImplicitCountDie = CUDie.addChild(DW_TAG_subrange_type);125  TypeImplicitCountDie.addAttribute(DW_AT_count, DW_FORM_implicit_const, 1);126 127  dwarfgen::DIE TypeValueRangeDie = CUDie.addChild(DW_TAG_subrange_type);128  TypeValueRangeDie.addAttribute(DW_AT_lower_bound, DW_FORM_data4, 1);129  TypeValueRangeDie.addAttribute(DW_AT_upper_bound, DW_FORM_data4, 2);130 131  dwarfgen::DIE TypeNoValueRangeDie = CUDie.addChild(DW_TAG_subrange_type);132  TypeNoValueRangeDie.addAttribute(DW_AT_lower_bound, DW_FORM_addr, 3);133  TypeNoValueRangeDie.addAttribute(DW_AT_upper_bound, DW_FORM_addr, 4);134 135  dwarfgen::DIE TypeImplicitRangeDie = CUDie.addChild(DW_TAG_subrange_type);136  TypeImplicitRangeDie.addAttribute(DW_AT_lower_bound, DW_FORM_implicit_const,137                                    5);138  TypeImplicitRangeDie.addAttribute(DW_AT_upper_bound, DW_FORM_implicit_const,139                                    6);140 141  // Generate the DWARF.142  StringRef FileBytes = DG->generate();143  MemoryBufferRef FileBuffer(FileBytes, "dwarf");144  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);145  EXPECT_TRUE((bool)Obj);146  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);147 148  // Verify the number of compile units is correct.149  uint32_t NumCUs = DwarfContext->getNumCompileUnits();150  EXPECT_EQ(NumCUs, 1u);151  DWARFCompileUnit *U = cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));152  auto DieDG = U->getUnitDIE(false);153  EXPECT_TRUE(DieDG.isValid());154 155  // Verify the siblings correct order.156  //   ScopeValue157  //   ScopeNoValue158  //   ScopeImplicit159  auto ScopeValueDieDG = DieDG.getFirstChild();160  EXPECT_TRUE(ScopeValueDieDG.isValid());161  EXPECT_EQ(ScopeValueDieDG.getTag(), DW_TAG_inlined_subroutine);162  auto ScopeNoValueDieDG = ScopeValueDieDG.getSibling();163  EXPECT_TRUE(ScopeNoValueDieDG.isValid());164  EXPECT_EQ(ScopeNoValueDieDG.getTag(), DW_TAG_inlined_subroutine);165  auto ScopeImplicitDieDG = ScopeNoValueDieDG.getSibling();166  EXPECT_TRUE(ScopeImplicitDieDG.isValid());167  EXPECT_EQ(ScopeImplicitDieDG.getTag(), DW_TAG_inlined_subroutine);168 169  // Verify the siblings correct order.170  //   SymbolValue171  //   SymbolNoValue172  //   SymbolImplicitValue173  auto SymbolValueDieDG = ScopeImplicitDieDG.getSibling();174  EXPECT_TRUE(SymbolValueDieDG.isValid());175  EXPECT_EQ(SymbolValueDieDG.getTag(), DW_TAG_variable);176  auto SymbolNoValueDieDG = SymbolValueDieDG.getSibling();177  EXPECT_TRUE(SymbolNoValueDieDG.isValid());178  EXPECT_EQ(SymbolNoValueDieDG.getTag(), DW_TAG_variable);179  auto SymbolImplicitDieDG = SymbolNoValueDieDG.getSibling();180  EXPECT_TRUE(SymbolImplicitDieDG.isValid());181  EXPECT_EQ(SymbolImplicitDieDG.getTag(), DW_TAG_variable);182 183  // Verify the siblings correct order.184  //   TypeValueCount185  //   TypeNoValueCount186  //   TypeImplicitValueCount187  auto TypeValueCountDieDG = SymbolImplicitDieDG.getSibling();188  EXPECT_TRUE(TypeValueCountDieDG.isValid());189  EXPECT_EQ(TypeValueCountDieDG.getTag(), DW_TAG_subrange_type);190  auto TypeNoValueCountDieDG = TypeValueCountDieDG.getSibling();191  EXPECT_TRUE(TypeNoValueCountDieDG.isValid());192  EXPECT_EQ(TypeNoValueCountDieDG.getTag(), DW_TAG_subrange_type);193  auto TypeImplicitCountDieDG = TypeNoValueCountDieDG.getSibling();194  EXPECT_TRUE(TypeImplicitCountDieDG.isValid());195  EXPECT_EQ(TypeImplicitCountDieDG.getTag(), DW_TAG_subrange_type);196 197  // Verify the siblings correct order.198  //   TypeValueRange199  //   TypeNoValueRange200  //   TypeImplicitValueRange201  auto TypeValueRangeDieDG = TypeImplicitCountDieDG.getSibling();202  EXPECT_TRUE(TypeValueRangeDieDG.isValid());203  EXPECT_EQ(TypeValueRangeDieDG.getTag(), DW_TAG_subrange_type);204  auto TypeNoValueRangeDieDG = TypeValueRangeDieDG.getSibling();205  EXPECT_TRUE(TypeNoValueRangeDieDG.isValid());206  EXPECT_EQ(TypeNoValueRangeDieDG.getTag(), DW_TAG_subrange_type);207  auto TypeImplicitRangeDieDG = TypeNoValueRangeDieDG.getSibling();208  EXPECT_TRUE(TypeImplicitRangeDieDG.isValid());209  EXPECT_EQ(TypeImplicitRangeDieDG.getTag(), DW_TAG_subrange_type);210 211  // Save the generated DWARF file to disk.212  EXPECT_TRUE(DG->saveFile(Path));213}214 215// Check the logical elements basic properties.216void checkElementAttributes(LVReader *Reader) {217  LVScopeRoot *Root = Reader->getScopesRoot();218  ASSERT_NE(Root, nullptr);219  LVScopeCompileUnit *CompileUnit = getFirstCompileUnit(Root);220  ASSERT_NE(CompileUnit, nullptr);221 222  const LVScopes *Scopes = CompileUnit->getScopes();223  ASSERT_NE(Scopes, nullptr);224  ASSERT_EQ(Scopes->size(), 3u);225 226  // Check values.227  LVScopes::const_iterator ScopeIter = Scopes->begin();228  ASSERT_NE(ScopeIter, Scopes->end());229  LVScope *Scope = static_cast<LVScope *>(*ScopeIter);230  ASSERT_NE(Scope, nullptr);231  EXPECT_EQ(Scope->getAccessibilityCode(), 1u); // Element232  EXPECT_EQ(Scope->getInlineCode(), 2u);        // Element233  EXPECT_EQ(Scope->getVirtualityCode(), 3u);    // Element234  EXPECT_EQ(Scope->getCallFilenameIndex(), 5u); // ScopeFunctionInlined235  EXPECT_EQ(Scope->getCallLineNumber(), 5u);    // ScopeFunctionInlined236  EXPECT_EQ(Scope->getFilenameIndex(), 7u);     // Element237  EXPECT_EQ(Scope->getLineNumber(), 7u);        // Element238  EXPECT_EQ(Scope->getDiscriminator(), 8u);     // ScopeFunctionInlined239 240  // Check no-values.241  ASSERT_NE(++ScopeIter, Scopes->end());242  Scope = static_cast<LVScope *>(*ScopeIter);243  ASSERT_NE(Scope, nullptr);244  EXPECT_EQ(Scope->getAccessibilityCode(), 0u); // Element245  EXPECT_EQ(Scope->getInlineCode(), 0u);        // Element246  EXPECT_EQ(Scope->getVirtualityCode(), 0u);    // Element247  EXPECT_EQ(Scope->getCallFilenameIndex(), 1u); // ScopeFunctionInlined248  EXPECT_EQ(Scope->getCallLineNumber(), 0u);    // ScopeFunctionInlined249  EXPECT_EQ(Scope->getFilenameIndex(), 1u);     // Element250  EXPECT_EQ(Scope->getLineNumber(), 0u);        // Element251  EXPECT_EQ(Scope->getDiscriminator(), 0u);     // ScopeFunctionInlined252 253  // Check implicit values.254  ASSERT_NE(++ScopeIter, Scopes->end());255  Scope = static_cast<LVScope *>(*ScopeIter);256  ASSERT_NE(Scope, nullptr);257  EXPECT_EQ(Scope->getAccessibilityCode(), 1u); // Element258  EXPECT_EQ(Scope->getInlineCode(), 2u);        // Element259  EXPECT_EQ(Scope->getVirtualityCode(), 3u);    // Element260  EXPECT_EQ(Scope->getCallFilenameIndex(), 5u); // ScopeFunctionInlined261  EXPECT_EQ(Scope->getCallLineNumber(), 5u);    // ScopeFunctionInlined262  EXPECT_EQ(Scope->getFilenameIndex(), 7u);     // Element263  EXPECT_EQ(Scope->getLineNumber(), 7u);        // Element264  EXPECT_EQ(Scope->getDiscriminator(), 8u);     // ScopeFunctionInlined265 266  const LVSymbols *Symbols = CompileUnit->getSymbols();267  ASSERT_NE(Symbols, nullptr);268  ASSERT_EQ(Symbols->size(), 3u);269 270  LVSymbols::const_iterator SymbolIter = Symbols->begin();271  ASSERT_NE(SymbolIter, Symbols->end());272  LVSymbol *Symbol = static_cast<LVSymbol *>(*SymbolIter);273  ASSERT_NE(Symbol, nullptr);274  EXPECT_EQ(Symbol->getBitSize(), 1u); // Symbol275 276  ASSERT_NE(++SymbolIter, Symbols->end());277  Symbol = static_cast<LVSymbol *>(*SymbolIter);278  ASSERT_NE(Symbol, nullptr);279  EXPECT_EQ(Symbol->getBitSize(), 0u); // Symbol280 281  ASSERT_NE(++SymbolIter, Symbols->end());282  Symbol = static_cast<LVSymbol *>(*SymbolIter);283  ASSERT_NE(Symbol, nullptr);284  EXPECT_EQ(Symbol->getBitSize(), 1u); // Symbol285 286  const LVTypes *Types = CompileUnit->getTypes();287  ASSERT_NE(Types, nullptr);288  ASSERT_EQ(Types->size(), 6u);289 290  LVTypes::const_iterator TypeIter = Types->begin();291  ASSERT_NE(TypeIter, Types->end());292  LVType *Type = static_cast<LVType *>(*TypeIter);293  ASSERT_NE(Type, nullptr);294  EXPECT_EQ(Type->getCount(), 1u); // Type295 296  ASSERT_NE(++TypeIter, Types->end());297  Type = static_cast<LVType *>(*TypeIter);298  ASSERT_NE(Type, nullptr);299  EXPECT_EQ(Type->getCount(), 0u); // Type300 301  ASSERT_NE(++TypeIter, Types->end());302  Type = static_cast<LVType *>(*TypeIter);303  ASSERT_NE(Type, nullptr);304  EXPECT_EQ(Type->getCount(), 1u); // Type305 306  ASSERT_NE(++TypeIter, Types->end());307  Type = static_cast<LVType *>(*TypeIter);308  ASSERT_NE(Type, nullptr);309  EXPECT_EQ(Type->getLowerBound(), 1u); // Type310  EXPECT_EQ(Type->getUpperBound(), 2u); // Type311 312  ASSERT_NE(++TypeIter, Types->end());313  Type = static_cast<LVType *>(*TypeIter);314  ASSERT_NE(Type, nullptr);315  EXPECT_EQ(Type->getLowerBound(), 0u); // Type316  EXPECT_EQ(Type->getUpperBound(), 0u); // Type317 318  ASSERT_NE(++TypeIter, Types->end());319  Type = static_cast<LVType *>(*TypeIter);320  ASSERT_NE(Type, nullptr);321  EXPECT_EQ(Type->getLowerBound(), 5u); // Type322  EXPECT_EQ(Type->getUpperBound(), 6u); // Type323}324 325TEST(LogicalViewTest, ElementAttributes) {326  // Initialize targets and assembly printers/parsers.327  llvm::InitializeAllTargetInfos();328  llvm::InitializeAllTargetMCs();329  InitializeAllDisassemblers();330 331  llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);332 333  Triple Triple(Triple::normalize("x86_64-pc-linux-gnu"));334  if (!isConfigurationSupported(Triple))335    GTEST_SKIP();336 337  unittest::TempDir TestDirectory("dwarf-test", /*Unique=*/true);338  llvm::SmallString<128> DirName(TestDirectory.path());339  StringRef Filename("test.o");340  llvm::SmallString<128> Path(TestDirectory.path(Filename));341  generateDebugInfo(Path, Triple);342 343  // Reader options.344  LVOptions ReaderOptions;345  ReaderOptions.setPrintScopes();346  ReaderOptions.setPrintSymbols();347  ReaderOptions.setPrintTypes();348  ReaderOptions.resolveDependencies();349 350  std::vector<std::string> Objects;351  ScopedPrinter W(outs());352  LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);353 354  // Check logical elements properties.355  std::unique_ptr<LVReader> Reader =356      createReader(ReaderHandler, DirName, Filename);357  ASSERT_NE(Reader, nullptr);358 359  checkElementAttributes(Reader.get());360}361 362} // namespace363