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