brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.8 KiB · 479b4a8 Raw
185 lines · cpp
1//===- llvm/unittest/MC/DwarfLineTables.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/ADT/STLExtras.h"10#include "llvm/ADT/StringExtras.h"11#include "llvm/BinaryFormat/Dwarf.h"12#include "llvm/MC/MCAsmInfo.h"13#include "llvm/MC/MCContext.h"14#include "llvm/MC/MCDwarf.h"15#include "llvm/MC/MCRegisterInfo.h"16#include "llvm/MC/MCTargetOptions.h"17#include "llvm/MC/TargetRegistry.h"18#include "llvm/Support/TargetSelect.h"19#include "gtest/gtest.h"20 21using namespace llvm;22 23namespace {24struct Context {25  static constexpr char TripleName[] = "x86_64-pc-linux";26  Triple TT;27  std::unique_ptr<MCRegisterInfo> MRI;28  std::unique_ptr<MCAsmInfo> MAI;29  std::unique_ptr<MCContext> Ctx;30 31  Context() : TT(TripleName) {32    llvm::InitializeAllTargetInfos();33    llvm::InitializeAllTargetMCs();34    llvm::InitializeAllDisassemblers();35 36    // If we didn't build x86, do not run the test.37    std::string Error;38    const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);39    if (!TheTarget)40      return;41 42    MRI.reset(TheTarget->createMCRegInfo(TT));43    MCTargetOptions MCOptions;44    MAI.reset(TheTarget->createMCAsmInfo(*MRI, TT, MCOptions));45    Ctx = std::make_unique<MCContext>(TT, MAI.get(), MRI.get(),46                                      /*MSTI=*/nullptr);47  }48 49  operator bool() { return Ctx.get(); }50  operator MCContext &() { return *Ctx; };51};52 53Context &getContext() {54  static Context Ctxt;55  return Ctxt;56}57}58 59void verifyEncoding(MCDwarfLineTableParams Params, int LineDelta, int AddrDelta,60                    ArrayRef<uint8_t> ExpectedEncoding) {61  SmallString<16> Buffer;62  MCDwarfLineAddr::encode(getContext(), Params, LineDelta, AddrDelta,63                          Buffer);64  EXPECT_EQ(ExpectedEncoding, arrayRefFromStringRef(Buffer));65}66 67TEST(DwarfLineTables, TestDefaultParams) {68  if (!getContext())69    GTEST_SKIP();70 71  MCDwarfLineTableParams Params;72 73  // Minimal line offset expressible through extended opcode, 0 addr delta74  const uint8_t Encoding0[] = {13}; // Special opcode Addr += 0, Line += -575  verifyEncoding(Params, -5, 0, Encoding0);76 77  // Maximal line offset expressible through extended opcode,78  const uint8_t Encoding1[] = {26}; // Special opcode Addr += 0, Line += +879  verifyEncoding(Params, 8, 0, Encoding1);80 81  // Random value in the middle of the special ocode range82  const uint8_t Encoding2[] = {146}; // Special opcode Addr += 9, Line += 283  verifyEncoding(Params, 2, 9, Encoding2);84 85  // Minimal line offset expressible through extended opcode, max addr delta86  const uint8_t Encoding3[] = {251}; // Special opcode Addr += 17, Line += -587  verifyEncoding(Params, -5, 17, Encoding3);88 89  // Biggest special opcode90  const uint8_t Encoding4[] = {255}; // Special opcode Addr += 17, Line += -191  verifyEncoding(Params, -1, 17, Encoding4);92 93  // Line delta outside of the special opcode range, address delta in range94  const uint8_t Encoding5[] = {dwarf::DW_LNS_advance_line, 9,95                               158}; // Special opcode Addr += 10, Line += 096  verifyEncoding(Params, 9, 10, Encoding5);97 98  // Address delta outside of the special opcode range, but small99  // enough to do DW_LNS_const_add_pc + special opcode.100  const uint8_t Encoding6[] = {dwarf::DW_LNS_const_add_pc, // pc += 17101                               62}; // Special opcode Addr += 3, Line += 2102  verifyEncoding(Params, 2, 20, Encoding6);103 104  // Address delta big enough to require the use of DW_LNS_advance_pc105  // Line delta in special opcode range106  const uint8_t Encoding7[] = {dwarf::DW_LNS_advance_pc, 100,107                               20}; // Special opcode Addr += 0, Line += 2108  verifyEncoding(Params, 2, 100, Encoding7);109 110  // No special opcode possible.111  const uint8_t Encoding8[] = {dwarf::DW_LNS_advance_line, 20,112                               dwarf::DW_LNS_advance_pc, 100,113                               dwarf::DW_LNS_copy};114  verifyEncoding(Params, 20, 100, Encoding8);115}116 117TEST(DwarfLineTables, TestCustomParams) {118  if (!getContext())119    GTEST_SKIP();120 121  // Some tests against the example values given in the standard.122  MCDwarfLineTableParams Params;123  Params.DWARF2LineOpcodeBase = 13;124  Params.DWARF2LineBase = -3;125  Params.DWARF2LineRange = 12;126 127  // Minimal line offset expressible through extended opcode, 0 addr delta128  const uint8_t Encoding0[] = {13}; // Special opcode Addr += 0, Line += -5129  verifyEncoding(Params, -3, 0, Encoding0);130 131  // Maximal line offset expressible through extended opcode,132  const uint8_t Encoding1[] = {24}; // Special opcode Addr += 0, Line += +8133  verifyEncoding(Params, 8, 0, Encoding1);134 135  // Random value in the middle of the special ocode range136  const uint8_t Encoding2[] = {126}; // Special opcode Addr += 9, Line += 2137  verifyEncoding(Params, 2, 9, Encoding2);138 139  // Minimal line offset expressible through extended opcode, max addr delta140  const uint8_t Encoding3[] = {253}; // Special opcode Addr += 20, Line += -3141  verifyEncoding(Params, -3, 20, Encoding3);142 143  // Biggest special opcode144  const uint8_t Encoding4[] = {255}; // Special opcode Addr += 17, Line += -1145  verifyEncoding(Params, -1, 20, Encoding4);146 147  // Line delta outside of the special opcode range, address delta in range148  const uint8_t Encoding5[] = {dwarf::DW_LNS_advance_line, 9,149                               136}; // Special opcode Addr += 10, Line += 0150  verifyEncoding(Params, 9, 10, Encoding5);151 152  // Address delta outside of the special opcode range, but small153  // enough to do DW_LNS_const_add_pc + special opcode.154  const uint8_t Encoding6[] = {dwarf::DW_LNS_const_add_pc, // pc += 20155                               138}; // Special opcode Addr += 10, Line += 2156  verifyEncoding(Params, 2, 30, Encoding6);157 158  // Address delta big enough to require the use of DW_LNS_advance_pc159  // Line delta in special opcode range160  const uint8_t Encoding7[] = {dwarf::DW_LNS_advance_pc, 100,161                               18}; // Special opcode Addr += 0, Line += 2162  verifyEncoding(Params, 2, 100, Encoding7);163 164  // No special opcode possible.165  const uint8_t Encoding8[] = {dwarf::DW_LNS_advance_line, 20,166                               dwarf::DW_LNS_advance_pc, 100,167                               dwarf::DW_LNS_copy};168  verifyEncoding(Params, 20, 100, Encoding8);169}170 171TEST(DwarfLineTables, TestCustomParams2) {172  if (!getContext())173    GTEST_SKIP();174 175  // Corner case param values.176  MCDwarfLineTableParams Params;177  Params.DWARF2LineOpcodeBase = 13;178  Params.DWARF2LineBase = 1;179  Params.DWARF2LineRange = 255;180 181  const uint8_t Encoding0[] = {dwarf::DW_LNS_advance_line, 248, 1,182                               dwarf::DW_LNS_copy};183  verifyEncoding(Params, 248, 0, Encoding0);184}185