172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===-- DIContext.h ---------------------------------------------*- C++ -*-===//
272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//                     The LLVM Compiler Infrastructure
472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// This file is distributed under the University of Illinois Open Source
672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// License. See LICENSE.TXT for details.
772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===----------------------------------------------------------------------===//
972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
10101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer// This file defines DIContext, an abstract data structure that holds
1172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// debug information data.
1272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
1372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===----------------------------------------------------------------------===//
1472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#ifndef LLVM_DEBUGINFO_DICONTEXT_H
1672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#define LLVM_DEBUGINFO_DICONTEXT_H
1772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
18806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher#include "llvm/ADT/DenseMap.h"
1971d94f805514f28730bf39143ee227648d521d09Alexey Samsonov#include "llvm/ADT/SmallString.h"
20255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth#include "llvm/ADT/SmallVector.h"
2172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/ADT/StringRef.h"
22d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher#include "llvm/Object/ObjectFile.h"
23d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher#include "llvm/Object/RelocVisitor.h"
24749d35c593eb3238c5dcb7284f1e3aee60d57b9eAlexey Samsonov#include "llvm/Support/Casting.h"
25c9935f378e5c593094e2bb3c8406256cd8f030d0Benjamin Kramer#include "llvm/Support/DataTypes.h"
2672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramernamespace llvm {
2872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerclass raw_ostream;
3072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
31101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer/// DILineInfo - a format-neutral container for source line information.
32101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramerclass DILineInfo {
3371d94f805514f28730bf39143ee227648d521d09Alexey Samsonov  SmallString<16> FileName;
3471d94f805514f28730bf39143ee227648d521d09Alexey Samsonov  SmallString<16> FunctionName;
35101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer  uint32_t Line;
36101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer  uint32_t Column;
37101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramerpublic:
383e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  DILineInfo()
393e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov    : FileName("<invalid>"), FunctionName("<invalid>"),
403e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov      Line(0), Column(0) {}
4171d94f805514f28730bf39143ee227648d521d09Alexey Samsonov  DILineInfo(const SmallString<16> &fileName,
4271d94f805514f28730bf39143ee227648d521d09Alexey Samsonov             const SmallString<16> &functionName,
433e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov             uint32_t line, uint32_t column)
443e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov    : FileName(fileName), FunctionName(functionName),
453e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov      Line(line), Column(column) {}
46101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer
4771d94f805514f28730bf39143ee227648d521d09Alexey Samsonov  const char *getFileName() { return FileName.c_str(); }
4871d94f805514f28730bf39143ee227648d521d09Alexey Samsonov  const char *getFunctionName() { return FunctionName.c_str(); }
49101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer  uint32_t getLine() const { return Line; }
50101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer  uint32_t getColumn() const { return Column; }
51ab6acef5317656212d80c289ea5b07c9deb30da0Benjamin Kramer
52ab6acef5317656212d80c289ea5b07c9deb30da0Benjamin Kramer  bool operator==(const DILineInfo &RHS) const {
53ab6acef5317656212d80c289ea5b07c9deb30da0Benjamin Kramer    return Line == RHS.Line && Column == RHS.Column &&
5471d94f805514f28730bf39143ee227648d521d09Alexey Samsonov           FileName.equals(RHS.FileName) &&
5571d94f805514f28730bf39143ee227648d521d09Alexey Samsonov           FunctionName.equals(RHS.FunctionName);
56ab6acef5317656212d80c289ea5b07c9deb30da0Benjamin Kramer  }
57ab6acef5317656212d80c289ea5b07c9deb30da0Benjamin Kramer  bool operator!=(const DILineInfo &RHS) const {
58ab6acef5317656212d80c289ea5b07c9deb30da0Benjamin Kramer    return !(*this == RHS);
59ab6acef5317656212d80c289ea5b07c9deb30da0Benjamin Kramer  }
60101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer};
61101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer
62e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylortypedef SmallVector<std::pair<uint64_t, DILineInfo>, 16> DILineInfoTable;
63e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
645eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov/// DIInliningInfo - a format-neutral container for inlined code description.
655eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonovclass DIInliningInfo {
665eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  SmallVector<DILineInfo, 4> Frames;
675eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov public:
685eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  DIInliningInfo() {}
695eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  DILineInfo getFrame(unsigned Index) const {
705eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    assert(Index < Frames.size());
715eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    return Frames[Index];
725eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  }
735eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  uint32_t getNumberOfFrames() const {
745eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    return Frames.size();
755eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  }
765eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  void addFrame(const DILineInfo &Frame) {
775eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    Frames.push_back(Frame);
785eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  }
795eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov};
805eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
813e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov/// DILineInfoSpecifier - controls which fields of DILineInfo container
823e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov/// should be filled with data.
833e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonovclass DILineInfoSpecifier {
843e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  const uint32_t Flags;  // Or'ed flags that set the info we want to fetch.
853e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonovpublic:
863e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  enum Specification {
873e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov    FileLineInfo = 1 << 0,
8871d94f805514f28730bf39143ee227648d521d09Alexey Samsonov    AbsoluteFilePath = 1 << 1,
8971d94f805514f28730bf39143ee227648d521d09Alexey Samsonov    FunctionName = 1 << 2
903e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  };
913e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  // Use file/line info by default.
923e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  DILineInfoSpecifier(uint32_t flags = FileLineInfo) : Flags(flags) {}
933e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  bool needs(Specification spec) const {
943e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov    return (Flags & spec) > 0;
953e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  }
963e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov};
973e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov
98939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky/// Selects which debug sections get dumped.
99939a4e8b693820d161f362317f7dba9057e66cc7Eli Benderskyenum DIDumpType {
100939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  DIDT_Null,
101939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  DIDT_All,
102939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  DIDT_Abbrev,
103939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  DIDT_AbbrevDwo,
104939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  DIDT_Aranges,
10560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  DIDT_Frames,
106939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  DIDT_Info,
107939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  DIDT_InfoDwo,
108939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  DIDT_Line,
1093df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  DIDT_Loc,
110939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  DIDT_Ranges,
111e38825f490b898644089d5cd9cb90cec681bded8Krzysztof Parzyszek  DIDT_Pubnames,
112939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  DIDT_Str,
113939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  DIDT_StrDwo,
114939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  DIDT_StrOffsetsDwo
115939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky};
116939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky
117806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher// In place of applying the relocations to the data we've read from disk we use
118eb3a8c5288110ddf183e3e8b8babc303f6b78020Eric Christopher// a separate mapping table to the side and checking that at locations in the
119eb3a8c5288110ddf183e3e8b8babc303f6b78020Eric Christopher// dwarf where we expect relocated values. This adds a bit of complexity to the
120eb3a8c5288110ddf183e3e8b8babc303f6b78020Eric Christopher// dwarf parsing/extraction at the benefit of not allocating memory for the
121eb3a8c5288110ddf183e3e8b8babc303f6b78020Eric Christopher// entire size of the debug info sections.
122806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christophertypedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap;
123806e03d2381709ddfb5a8012729bbe6eae12caf5Eric Christopher
12472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerclass DIContext {
12572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerpublic:
126749d35c593eb3238c5dcb7284f1e3aee60d57b9eAlexey Samsonov  enum DIContextKind {
127749d35c593eb3238c5dcb7284f1e3aee60d57b9eAlexey Samsonov    CK_DWARF
128749d35c593eb3238c5dcb7284f1e3aee60d57b9eAlexey Samsonov  };
129749d35c593eb3238c5dcb7284f1e3aee60d57b9eAlexey Samsonov  DIContextKind getKind() const { return Kind; }
130749d35c593eb3238c5dcb7284f1e3aee60d57b9eAlexey Samsonov
131749d35c593eb3238c5dcb7284f1e3aee60d57b9eAlexey Samsonov  DIContext(DIContextKind K) : Kind(K) {}
13272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  virtual ~DIContext();
13372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
13472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  /// getDWARFContext - get a context for binary DWARF data.
135d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher  static DIContext *getDWARFContext(object::ObjectFile *);
13672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
137939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) = 0;
138101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer
1395eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  virtual DILineInfo getLineInfoForAddress(uint64_t Address,
1405eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
141e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address,
142e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor      uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
1435eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address,
1445eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
145749d35c593eb3238c5dcb7284f1e3aee60d57b9eAlexey Samsonovprivate:
146749d35c593eb3238c5dcb7284f1e3aee60d57b9eAlexey Samsonov  const DIContextKind Kind;
14772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer};
14872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
14972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
15072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
15172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#endif
152