brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · 449442f Raw
228 lines · cpp
1//===- DWARFDataExtractorTest.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 "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"10#include "llvm/DebugInfo/DWARF/DWARFContext.h"11#include "llvm/Object/ObjectFile.h"12#include "llvm/ObjectYAML/yaml2obj.h"13#include "llvm/Testing/Support/Error.h"14#include "gtest/gtest.h"15 16using namespace llvm;17 18namespace {19 20TEST(DWARFDataExtractorTest, getRelocatedValue) {21  StringRef Yaml = R"(22!ELF23FileHeader:24  Class:    ELFCLASS3225  Data:     ELFDATA2LSB26  Type:     ET_REL27  Machine:  EM_38628Sections:29  - Name:     .text30    Type:     SHT_PROGBITS31    Size:     0x8032  - Name:     .debug_line33    Type:     SHT_PROGBITS34    Content:  '000000000000'35  - Name:     .rel.debug_line36    Type:     SHT_REL37    Info:     .debug_line38    Relocations:39      - Offset:   040        Symbol:   f41        Type:     R_386_3242      - Offset:   443        Symbol:   f44        Type:     R_386_3245Symbols:46  - Name:     f47    Type:     STT_SECTION48    Section:  .text49    Value:    0x4250)";51  SmallString<0> Storage;52  std::unique_ptr<object::ObjectFile> Obj = yaml::yaml2ObjectFile(53      Storage, Yaml, [](const Twine &Err) { errs() << Err; });54  ASSERT_TRUE(Obj);55  std::unique_ptr<DWARFContext> Ctx = DWARFContext::create(*Obj);56  const DWARFObject &DObj = Ctx->getDWARFObj();57  ASSERT_EQ(6u, DObj.getLineSection().Data.size());58 59  DWARFDataExtractor Data(DObj, DObj.getLineSection(), Obj->isLittleEndian(),60                          Obj->getBytesInAddress());61  DataExtractor::Cursor C(0);62  EXPECT_EQ(0x42u, Data.getRelocatedAddress(C));63  EXPECT_EQ(0u, Data.getRelocatedAddress(C));64  EXPECT_THAT_ERROR(65      C.takeError(),66      FailedWithMessage(67          "unexpected end of data at offset 0x6 while reading [0x4, 0x8)"));68}69 70TEST(DWARFDataExtractorTest, getInitialLength) {71  auto GetWithError = [](ArrayRef<uint8_t> Bytes)72      -> Expected<std::tuple<uint64_t, dwarf::DwarfFormat, uint64_t>> {73    DWARFDataExtractor Data(Bytes, /*IsLittleEndian=*/false, /*AddressSize=*/8);74    DWARFDataExtractor::Cursor C(0);75    uint64_t Length;76    dwarf::DwarfFormat Format;77    std::tie(Length, Format) = Data.getInitialLength(C);78    if (C)79      return std::make_tuple(Length, Format, C.tell());80 81    EXPECT_EQ(Length, 0u);82    EXPECT_EQ(Format, dwarf::DWARF32);83    EXPECT_EQ(C.tell(), 0u);84    return C.takeError();85  };86  auto GetWithoutError = [](ArrayRef<uint8_t> Bytes) {87    DWARFDataExtractor Data(Bytes, /*IsLittleEndian=*/false, /*AddressSize=*/8);88    uint64_t Offset = 0;89    uint64_t Length;90    dwarf::DwarfFormat Format;91    std::tie(Length, Format) = Data.getInitialLength(&Offset);92    return std::make_tuple(Length, Format, Offset);93  };94  auto ErrorResult = std::make_tuple(0, dwarf::DWARF32, 0);95 96  // Empty data.97  EXPECT_THAT_EXPECTED(98      GetWithError({}),99      FailedWithMessage(100          "unexpected end of data at offset 0x0 while reading [0x0, 0x4)"));101  EXPECT_EQ(GetWithoutError({}), ErrorResult);102 103  // Not long enough for the U32 field.104  EXPECT_THAT_EXPECTED(105      GetWithError({0x00, 0x01, 0x02}),106      FailedWithMessage(107          "unexpected end of data at offset 0x3 while reading [0x0, 0x4)"));108  EXPECT_EQ(GetWithoutError({0x00, 0x01, 0x02}), ErrorResult);109 110  EXPECT_THAT_EXPECTED(111      GetWithError({0x00, 0x01, 0x02, 0x03}),112      HasValue(std::make_tuple(0x00010203, dwarf::DWARF32, 4)));113  EXPECT_EQ(GetWithoutError({0x00, 0x01, 0x02, 0x03}),114            std::make_tuple(0x00010203, dwarf::DWARF32, 4));115 116  // Zeroes are not an error, but without the Error object it is hard to tell117  // them apart from a failed read.118  EXPECT_THAT_EXPECTED(119      GetWithError({0x00, 0x00, 0x00, 0x00}),120      HasValue(std::make_tuple(0x00000000, dwarf::DWARF32, 4)));121  EXPECT_EQ(GetWithoutError({0x00, 0x00, 0x00, 0x00}),122            std::make_tuple(0x00000000, dwarf::DWARF32, 4));123 124  // Smallest invalid value.125  EXPECT_THAT_EXPECTED(126      GetWithError({0xff, 0xff, 0xff, 0xf0}),127      FailedWithMessage(128          "unsupported reserved unit length of value 0xfffffff0"));129  EXPECT_EQ(GetWithoutError({0xff, 0xff, 0xff, 0xf0}), ErrorResult);130 131  // DWARF64 marker without the subsequent length field.132  EXPECT_THAT_EXPECTED(133      GetWithError({0xff, 0xff, 0xff, 0xff}),134      FailedWithMessage(135          "unexpected end of data at offset 0x4 while reading [0x4, 0xc)"));136  EXPECT_EQ(GetWithoutError({0xff, 0xff, 0xff, 0xff}), ErrorResult);137 138  // Not enough data for the U64 length.139  EXPECT_THAT_EXPECTED(140      GetWithError({0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03}),141      FailedWithMessage(142          "unexpected end of data at offset 0x8 while reading [0x4, 0xc)"));143  EXPECT_EQ(GetWithoutError({0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03}),144            ErrorResult);145 146  EXPECT_THAT_EXPECTED(147      GetWithError({0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,148                    0x06, 0x07}),149      HasValue(std::make_tuple(0x0001020304050607, dwarf::DWARF64, 12)));150  EXPECT_EQ(GetWithoutError({0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03,151                             0x04, 0x05, 0x06, 0x07}),152            std::make_tuple(0x0001020304050607, dwarf::DWARF64, 12));153}154 155TEST(DWARFDataExtractorTest, Truncation) {156  StringRef Yaml = R"(157!ELF158FileHeader:159  Class:    ELFCLASS32160  Data:     ELFDATA2LSB161  Type:     ET_REL162  Machine:  EM_386163Sections:164  - Name:     .text165    Type:     SHT_PROGBITS166    Size:     0x80167  - Name:     .debug_line168    Type:     SHT_PROGBITS169    Content:  '616263640000000065666768'170  - Name:     .rel.debug_line171    Type:     SHT_REL172    Info:     .debug_line173    Relocations:174      - Offset:   4175        Symbol:   f176        Type:     R_386_32177Symbols:178  - Name:     f179    Type:     STT_SECTION180    Section:  .text181    Value:    0x42182)";183  SmallString<0> Storage;184  std::unique_ptr<object::ObjectFile> Obj = yaml::yaml2ObjectFile(185      Storage, Yaml, [](const Twine &Err) { errs() << Err; });186  ASSERT_TRUE(Obj);187  std::unique_ptr<DWARFContext> Ctx = DWARFContext::create(*Obj);188  const DWARFObject &DObj = Ctx->getDWARFObj();189  ASSERT_EQ(12u, DObj.getLineSection().Data.size());190 191  DWARFDataExtractor Data(DObj, DObj.getLineSection(), Obj->isLittleEndian(),192                          Obj->getBytesInAddress());193  DataExtractor::Cursor C(0);194  EXPECT_EQ(0x64636261u, Data.getRelocatedAddress(C));195  EXPECT_EQ(0x42u, Data.getRelocatedAddress(C));196  EXPECT_EQ(0x68676665u, Data.getRelocatedAddress(C));197  EXPECT_THAT_ERROR(C.takeError(), Succeeded());198 199  C = DataExtractor::Cursor{0};200  DWARFDataExtractor Truncated8(Data, 8);201  EXPECT_EQ(0x64636261u, Truncated8.getRelocatedAddress(C));202  EXPECT_EQ(0x42u, Truncated8.getRelocatedAddress(C));203  EXPECT_EQ(0x0u, Truncated8.getRelocatedAddress(C));204  EXPECT_THAT_ERROR(205      C.takeError(),206      FailedWithMessage(207          "unexpected end of data at offset 0x8 while reading [0x8, 0xc)"));208 209  C = DataExtractor::Cursor{0};210  DWARFDataExtractor Truncated6(Data, 6);211  EXPECT_EQ(0x64636261u, Truncated6.getRelocatedAddress(C));212  EXPECT_EQ(0x0u, Truncated6.getRelocatedAddress(C));213  EXPECT_THAT_ERROR(214      C.takeError(),215      FailedWithMessage(216          "unexpected end of data at offset 0x6 while reading [0x4, 0x8)"));217 218  C = DataExtractor::Cursor{0};219  DWARFDataExtractor Truncated2(Data, 2);220  EXPECT_EQ(0x0u, Truncated2.getRelocatedAddress(C));221  EXPECT_THAT_ERROR(222      C.takeError(),223      FailedWithMessage(224          "unexpected end of data at offset 0x2 while reading [0x0, 0x4)"));225}226 227} // namespace228