summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/MCDwarf2BTF.cpp
blob: 08a70e6f318fbfa46cc4f1ed095ae3fe4c33cbb5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//===- MCDwarf2BTF.cpp ---------------------------------------- *- C++ --*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "MCDwarf2BTF.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCBTFContext.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/EndianStream.h"
#include <fstream>

using namespace llvm;

void MCDwarf2BTF::addFiles(MCObjectStreamer *MCOS, std::string &FileName,
  std::vector<FileContent> &Files) {
  std::vector<std::string> Content;

  std::ifstream Inputfile(FileName);
  std::string Line;
  Content.push_back(Line); // line 0 for empty string
  while (std::getline(Inputfile, Line))
    Content.push_back(Line);

  Files.push_back(FileContent(FileName, Content));
}

void MCDwarf2BTF::addLines(MCObjectStreamer *MCOS, StringRef &SectionName,
  std::vector<FileContent> &Files,
  const MCLineSection::MCDwarfLineEntryCollection &LineEntries) {
  MCContext &Context = MCOS->getContext();
  auto &BTFCxt = Context.getBTFContext();

  unsigned SecNameOff = BTFCxt->addString(SectionName.str());
  for (const MCDwarfLineEntry &LineEntry : LineEntries) {
    BTFLineInfo LineInfo;
    unsigned FileNum = LineEntry.getFileNum();
    unsigned Line = LineEntry.getLine();

    LineInfo.Label = LineEntry.getLabel();
    if (FileNum < Files.size()) {
      LineInfo.FileNameOff = BTFCxt->addString(Files[FileNum].first);
      if (Line < Files[FileNum].second.size())
        LineInfo.LineOff = BTFCxt->addString(Files[FileNum].second[Line]);
      else
        LineInfo.LineOff = 0;
    } else {
      LineInfo.FileNameOff = 0;
      LineInfo.LineOff = 0;
    }
    LineInfo.LineNum = Line;
    LineInfo.ColumnNum = LineEntry.getColumn();
    BTFCxt->addLineInfo(SecNameOff, LineInfo);
  }
}

void MCDwarf2BTF::addDwarfLineInfo(MCObjectStreamer *MCOS) {
  MCContext &Context = MCOS->getContext();

  auto &LineTables = Context.getMCDwarfLineTables();
  if (LineTables.empty())
    return;

  for (const auto &CUIDTablePair : LineTables) {
    std::vector<std::string> Dirs;
    std::vector<FileContent> Files;

    for (auto &Dir : CUIDTablePair.second.getMCDwarfDirs())
      Dirs.push_back(Dir);
    for (auto &File : CUIDTablePair.second.getMCDwarfFiles()) {
      std::string FileName;
      if (File.DirIndex == 0)
        FileName = File.Name;
      else
        FileName = Dirs[File.DirIndex - 1] + "/" + File.Name;
      MCDwarf2BTF::addFiles(MCOS, FileName, Files);
    }
    for (const auto &LineSec: CUIDTablePair.second.getMCLineSections().getMCLineEntries()) {
      MCSection *Section = LineSec.first;
      const MCLineSection::MCDwarfLineEntryCollection &LineEntries = LineSec.second;

      StringRef SectionName;
      if (MCSectionELF *SectionELF = dyn_cast<MCSectionELF>(Section))
        SectionName = SectionELF->getSectionName();
      else
        return;
      MCDwarf2BTF::addLines(MCOS, SectionName, Files, LineEntries);
    }
  }
}
OpenPOWER on IntegriCloud