Compare commits
64 Commits
module
...
llvmorg-3.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc9407d0e8 | ||
|
|
ecf0769549 | ||
|
|
97ba845838 | ||
|
|
491019467c | ||
|
|
6131d993df | ||
|
|
12bfc7914b | ||
|
|
aee68a10e7 | ||
|
|
3a2254cbcb | ||
|
|
b4a5136638 | ||
|
|
5817c40379 | ||
|
|
925024ef0a | ||
|
|
4122a1132c | ||
|
|
6a44832760 | ||
|
|
8e7812f680 | ||
|
|
474d7226a0 | ||
|
|
e45cf9ef9f | ||
|
|
377aca8d42 | ||
|
|
2b2cfe2ead | ||
|
|
bb15689d96 | ||
|
|
3493a5de9d | ||
|
|
b9f7abc7cc | ||
|
|
5d6720886c | ||
|
|
85debca4cb | ||
|
|
68fa59d902 | ||
|
|
97fa7e0ee2 | ||
|
|
9eb29f154c | ||
|
|
20529b792b | ||
|
|
24e86d5820 | ||
|
|
fff6b94f92 | ||
|
|
ef34692ce0 | ||
|
|
ff7a27c82b | ||
|
|
3e8b49ff47 | ||
|
|
440ca6f9f1 | ||
|
|
2406e73c0e | ||
|
|
6b0c30492b | ||
|
|
b5cd42ab52 | ||
|
|
7355790567 | ||
|
|
9feb000b5d | ||
|
|
e0f468e366 | ||
|
|
d71be28020 | ||
|
|
a6c52d2c2c | ||
|
|
514c81fdf1 | ||
|
|
274c302dde | ||
|
|
b35703c039 | ||
|
|
2d66439333 | ||
|
|
9517c0fdb2 | ||
|
|
f67c377203 | ||
|
|
906cc78d7c | ||
|
|
e6d5fab835 | ||
|
|
a3e5429d9b | ||
|
|
2723da100f | ||
|
|
9e7107c9d9 | ||
|
|
c7248e8f2b | ||
|
|
2dfa76cecd | ||
|
|
29ef90e6c4 | ||
|
|
58de1fdf54 | ||
|
|
ac42e4daef | ||
|
|
5ebd8c9a1c | ||
|
|
c1174de9f4 | ||
|
|
0389c51dcb | ||
|
|
229865e2a4 | ||
|
|
6cf1189fe7 | ||
|
|
e43a4cbd5f | ||
|
|
ebcd208ddd |
@@ -815,7 +815,7 @@ class Cursor(Structure):
|
||||
The Cursor class represents a reference to an element within the AST. It
|
||||
acts as a kind of iterator.
|
||||
"""
|
||||
_fields_ = [("_kind_id", c_int), ("data", c_void_p * 3)]
|
||||
_fields_ = [("_kind_id", c_int), ("xdata", c_int), ("data", c_void_p * 3)]
|
||||
|
||||
def __eq__(self, other):
|
||||
return Cursor_eq(self, other)
|
||||
@@ -1019,7 +1019,7 @@ TypeKind.OBJCINTERFACE = TypeKind(108)
|
||||
TypeKind.OBJCOBJECTPOINTER = TypeKind(109)
|
||||
TypeKind.FUNCTIONNOPROTO = TypeKind(110)
|
||||
TypeKind.FUNCTIONPROTO = TypeKind(111)
|
||||
|
||||
TypeKind.CONSTANTARRAY = TypeKind(112)
|
||||
|
||||
class Type(Structure):
|
||||
"""
|
||||
|
||||
@@ -74,3 +74,22 @@ def test_a_struct():
|
||||
|
||||
else:
|
||||
assert False, "Didn't find teststruct??"
|
||||
|
||||
|
||||
constarrayInput="""
|
||||
struct teststruct {
|
||||
void *A[2];
|
||||
};
|
||||
"""
|
||||
def testConstantArray():
|
||||
index = Index.create()
|
||||
tu = index.parse('t.c', unsaved_files = [('t.c',constarrayInput)])
|
||||
|
||||
for n in tu.cursor.get_children():
|
||||
if n.spelling == 'teststruct':
|
||||
fields = list(n.get_children())
|
||||
assert fields[0].spelling == 'A'
|
||||
assert fields[0].type.kind == TypeKind.CONSTANTARRAY
|
||||
break
|
||||
else:
|
||||
assert False, "Didn't find teststruct??"
|
||||
|
||||
@@ -39,7 +39,7 @@ OUTPUT_DIRECTORY = @abs_builddir@/doxygen
|
||||
# source files, where putting all generated files in the same directory would
|
||||
# otherwise cause performance problems for the file system.
|
||||
|
||||
CREATE_SUBDIRS = NO
|
||||
CREATE_SUBDIRS = YES
|
||||
|
||||
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
|
||||
# documentation generated by doxygen is written. Doxygen will use this
|
||||
|
||||
@@ -206,7 +206,6 @@ public:
|
||||
/// \brief Reset any options that are not considered when building a
|
||||
/// module.
|
||||
void resetNonModularOptions() {
|
||||
Macros.clear();
|
||||
Includes.clear();
|
||||
MacroIncludes.clear();
|
||||
ChainedIncludes.clear();
|
||||
|
||||
@@ -247,11 +247,12 @@ protected:
|
||||
MacroBuilder &Builder) const {
|
||||
// FreeBSD defines; list based off of gcc output
|
||||
|
||||
// FIXME: Move version number handling to llvm::Triple.
|
||||
StringRef Release = Triple.getOSName().substr(strlen("freebsd"), 1);
|
||||
unsigned Release = Triple.getOSMajorVersion();
|
||||
if (Release == 0U)
|
||||
Release = 8;
|
||||
|
||||
Builder.defineMacro("__FreeBSD__", Release);
|
||||
Builder.defineMacro("__FreeBSD_cc_version", Release + "00001");
|
||||
Builder.defineMacro("__FreeBSD__", Twine(Release));
|
||||
Builder.defineMacro("__FreeBSD_cc_version", Twine(Release * 100000U + 1U));
|
||||
Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
|
||||
DefineStd(Builder, "unix", Opts);
|
||||
Builder.defineMacro("__ELF__");
|
||||
|
||||
@@ -538,11 +538,12 @@ protected:
|
||||
llvm::Value *cmd,
|
||||
llvm::MDNode *node) {
|
||||
CGBuilderTy &Builder = CGF.Builder;
|
||||
llvm::Value *imp = Builder.CreateCall2(MsgLookupFn,
|
||||
EnforceType(Builder, Receiver, IdTy),
|
||||
EnforceType(Builder, cmd, SelectorTy));
|
||||
cast<llvm::CallInst>(imp)->setMetadata(msgSendMDKind, node);
|
||||
return imp;
|
||||
llvm::Value *args[] = {
|
||||
EnforceType(Builder, Receiver, IdTy),
|
||||
EnforceType(Builder, cmd, SelectorTy) };
|
||||
llvm::CallSite imp = CGF.EmitCallOrInvoke(MsgLookupFn, args);
|
||||
imp->setMetadata(msgSendMDKind, node);
|
||||
return imp.getInstruction();
|
||||
}
|
||||
virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF,
|
||||
llvm::Value *ObjCSuper,
|
||||
@@ -597,16 +598,17 @@ class CGObjCGNUstep : public CGObjCGNU {
|
||||
// The lookup function is guaranteed not to capture the receiver pointer.
|
||||
LookupFn->setDoesNotCapture(1);
|
||||
|
||||
llvm::CallInst *slot =
|
||||
Builder.CreateCall3(LookupFn,
|
||||
EnforceType(Builder, ReceiverPtr, PtrToIdTy),
|
||||
EnforceType(Builder, cmd, SelectorTy),
|
||||
EnforceType(Builder, self, IdTy));
|
||||
slot->setOnlyReadsMemory();
|
||||
llvm::Value *args[] = {
|
||||
EnforceType(Builder, ReceiverPtr, PtrToIdTy),
|
||||
EnforceType(Builder, cmd, SelectorTy),
|
||||
EnforceType(Builder, self, IdTy) };
|
||||
llvm::CallSite slot = CGF.EmitCallOrInvoke(LookupFn, args);
|
||||
slot.setOnlyReadsMemory();
|
||||
slot->setMetadata(msgSendMDKind, node);
|
||||
|
||||
// Load the imp from the slot
|
||||
llvm::Value *imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4));
|
||||
llvm::Value *imp =
|
||||
Builder.CreateLoad(Builder.CreateStructGEP(slot.getInstruction(), 4));
|
||||
|
||||
// The lookup function may have changed the receiver, so make sure we use
|
||||
// the new one.
|
||||
@@ -1361,8 +1363,8 @@ llvm::Constant *CGObjCGNU::GenerateClassStructure(
|
||||
LongTy, // abi_version
|
||||
IvarOffsets->getType(), // ivar_offsets
|
||||
Properties->getType(), // properties
|
||||
Int64Ty, // strong_pointers
|
||||
Int64Ty, // weak_pointers
|
||||
IntPtrTy, // strong_pointers
|
||||
IntPtrTy, // weak_pointers
|
||||
NULL);
|
||||
llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
|
||||
// Fill in the structure
|
||||
@@ -1723,12 +1725,14 @@ void CGObjCGNU::GenerateProtocolHolderCategory(void) {
|
||||
/// bitfield / with the 63rd bit set will be 1<<64.
|
||||
llvm::Constant *CGObjCGNU::MakeBitField(llvm::SmallVectorImpl<bool> &bits) {
|
||||
int bitCount = bits.size();
|
||||
if (bitCount < 64) {
|
||||
int ptrBits =
|
||||
(TheModule.getPointerSize() == llvm::Module::Pointer32) ? 32 : 64;
|
||||
if (bitCount < ptrBits) {
|
||||
uint64_t val = 1;
|
||||
for (int i=0 ; i<bitCount ; ++i) {
|
||||
if (bits[i]) val |= 1ULL<<(i+1);
|
||||
}
|
||||
return llvm::ConstantInt::get(Int64Ty, val);
|
||||
return llvm::ConstantInt::get(IntPtrTy, val);
|
||||
}
|
||||
llvm::SmallVector<llvm::Constant*, 8> values;
|
||||
int v=0;
|
||||
@@ -1748,8 +1752,6 @@ llvm::Constant *CGObjCGNU::MakeBitField(llvm::SmallVectorImpl<bool> &bits) {
|
||||
llvm::Constant *GS = MakeGlobal(llvm::StructType::get(Int32Ty, arrayTy,
|
||||
NULL), fields);
|
||||
llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
|
||||
if (IntPtrTy != Int64Ty)
|
||||
ptr = llvm::ConstantExpr::getZExt(ptr, Int64Ty);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -2073,12 +2075,12 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
|
||||
}
|
||||
++ivarIndex;
|
||||
}
|
||||
llvm::Constant *Zero64 = llvm::ConstantInt::get(Int64Ty, 0);
|
||||
llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
|
||||
//Generate metaclass for class methods
|
||||
llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
|
||||
NULLPtr, 0x12L, ClassName.c_str(), 0, Zeros[0], GenerateIvarList(
|
||||
empty, empty, empty), ClassMethodList, NULLPtr,
|
||||
NULLPtr, NULLPtr, Zero64, Zero64, true);
|
||||
NULLPtr, NULLPtr, ZeroPtr, ZeroPtr, true);
|
||||
|
||||
// Generate the class structure
|
||||
llvm::Constant *ClassStruct =
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
@@ -858,6 +859,59 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct FunctionIsDirectlyRecursive :
|
||||
public RecursiveASTVisitor<FunctionIsDirectlyRecursive> {
|
||||
const StringRef Name;
|
||||
bool Result;
|
||||
FunctionIsDirectlyRecursive(const FunctionDecl *F) :
|
||||
Name(F->getName()), Result(false) {
|
||||
}
|
||||
typedef RecursiveASTVisitor<FunctionIsDirectlyRecursive> Base;
|
||||
|
||||
bool TraverseCallExpr(CallExpr *E) {
|
||||
const Decl *D = E->getCalleeDecl();
|
||||
if (!D)
|
||||
return true;
|
||||
AsmLabelAttr *Attr = D->getAttr<AsmLabelAttr>();
|
||||
if (!Attr)
|
||||
return true;
|
||||
if (Name == Attr->getLabel()) {
|
||||
Result = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// isTriviallyRecursiveViaAsm - Check if this function calls another
|
||||
// decl that, because of the asm attribute, ends up pointing to itself.
|
||||
bool
|
||||
CodeGenModule::isTriviallyRecursiveViaAsm(const FunctionDecl *F) {
|
||||
if (getCXXABI().getMangleContext().shouldMangleDeclName(F))
|
||||
return false;
|
||||
|
||||
FunctionIsDirectlyRecursive Walker(F);
|
||||
Walker.TraverseFunctionDecl(const_cast<FunctionDecl*>(F));
|
||||
return Walker.Result;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenModule::shouldEmitFunction(const FunctionDecl *F) {
|
||||
if (getFunctionLinkage(F) != llvm::Function::AvailableExternallyLinkage)
|
||||
return true;
|
||||
if (CodeGenOpts.OptimizationLevel == 0 &&
|
||||
!F->hasAttr<AlwaysInlineAttr>())
|
||||
return false;
|
||||
// PR9614. Avoid cases where the source code is lying to us. An available
|
||||
// externally function should have an equivalent function somewhere else,
|
||||
// but a function that calls itself is clearly not equivalent to the real
|
||||
// implementation.
|
||||
// This happens in glibc's btowc and in some configure checks.
|
||||
return !isTriviallyRecursiveViaAsm(F);
|
||||
}
|
||||
|
||||
void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
|
||||
const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
|
||||
|
||||
@@ -868,10 +922,7 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
|
||||
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
|
||||
// At -O0, don't generate IR for functions with available_externally
|
||||
// linkage.
|
||||
if (CodeGenOpts.OptimizationLevel == 0 &&
|
||||
!Function->hasAttr<AlwaysInlineAttr>() &&
|
||||
getFunctionLinkage(Function)
|
||||
== llvm::Function::AvailableExternallyLinkage)
|
||||
if (!shouldEmitFunction(Function))
|
||||
return;
|
||||
|
||||
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
|
||||
|
||||
@@ -324,6 +324,8 @@ class CodeGenModule : public CodeGenTypeCache {
|
||||
void createOpenCLRuntime();
|
||||
void createCUDARuntime();
|
||||
|
||||
bool isTriviallyRecursiveViaAsm(const FunctionDecl *F);
|
||||
bool shouldEmitFunction(const FunctionDecl *F);
|
||||
llvm::LLVMContext &VMContext;
|
||||
|
||||
/// @name Cache for Blocks Runtime Globals
|
||||
|
||||
@@ -1631,14 +1631,12 @@ private:
|
||||
SmallVectorImpl<StringRef> &LibDirs,
|
||||
SmallVectorImpl<StringRef> &Triples) {
|
||||
if (HostArch == llvm::Triple::arm || HostArch == llvm::Triple::thumb) {
|
||||
static const char *const ARMLibDirs[] = { "/lib/gcc" };
|
||||
static const char *const ARMLibDirs[] = { "/lib" };
|
||||
static const char *const ARMTriples[] = { "arm-linux-gnueabi" };
|
||||
LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs));
|
||||
Triples.append(ARMTriples, ARMTriples + llvm::array_lengthof(ARMTriples));
|
||||
} else if (HostArch == llvm::Triple::x86_64) {
|
||||
static const char *const X86_64LibDirs[] = {
|
||||
"/lib64/gcc", "/lib/gcc", "/lib64", "/lib"
|
||||
};
|
||||
static const char *const X86_64LibDirs[] = { "/lib64", "/lib" };
|
||||
static const char *const X86_64Triples[] = {
|
||||
"x86_64-linux-gnu",
|
||||
"x86_64-unknown-linux-gnu",
|
||||
@@ -1655,9 +1653,7 @@ private:
|
||||
Triples.append(X86_64Triples,
|
||||
X86_64Triples + llvm::array_lengthof(X86_64Triples));
|
||||
} else if (HostArch == llvm::Triple::x86) {
|
||||
static const char *const X86LibDirs[] = {
|
||||
"/lib32/gcc", "/lib/gcc", "/lib32", "/lib"
|
||||
};
|
||||
static const char *const X86LibDirs[] = { "/lib32", "/lib" };
|
||||
static const char *const X86Triples[] = {
|
||||
"i686-linux-gnu",
|
||||
"i386-linux-gnu",
|
||||
@@ -1671,9 +1667,7 @@ private:
|
||||
LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs));
|
||||
Triples.append(X86Triples, X86Triples + llvm::array_lengthof(X86Triples));
|
||||
} else if (HostArch == llvm::Triple::ppc) {
|
||||
static const char *const PPCLibDirs[] = {
|
||||
"/lib32/gcc", "/lib/gcc", "/lib32", "/lib"
|
||||
};
|
||||
static const char *const PPCLibDirs[] = { "/lib32", "/lib" };
|
||||
static const char *const PPCTriples[] = {
|
||||
"powerpc-linux-gnu",
|
||||
"powerpc-unknown-linux-gnu"
|
||||
@@ -1681,9 +1675,7 @@ private:
|
||||
LibDirs.append(PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs));
|
||||
Triples.append(PPCTriples, PPCTriples + llvm::array_lengthof(PPCTriples));
|
||||
} else if (HostArch == llvm::Triple::ppc64) {
|
||||
static const char *const PPC64LibDirs[] = {
|
||||
"/lib64/gcc", "/lib/gcc", "/lib64", "/lib"
|
||||
};
|
||||
static const char *const PPC64LibDirs[] = { "/lib64", "/lib" };
|
||||
static const char *const PPC64Triples[] = {
|
||||
"powerpc64-unknown-linux-gnu"
|
||||
};
|
||||
@@ -1697,23 +1689,31 @@ private:
|
||||
void ScanLibDirForGCCTriple(const std::string &LibDir,
|
||||
StringRef CandidateTriple,
|
||||
GCCVersion &BestVersion) {
|
||||
const std::string TripleDir = LibDir + "/" + CandidateTriple.str();
|
||||
if (!PathExists(TripleDir))
|
||||
return;
|
||||
|
||||
// There are various different suffixes on the triple directory we
|
||||
// There are various different suffixes involving the triple we
|
||||
// check for. We also record what is necessary to walk from each back
|
||||
// up to the lib directory.
|
||||
const std::string Suffixes[] = { "", "/gcc/" + CandidateTriple.str(),
|
||||
"/gcc/i686-linux-gnu" };
|
||||
const std::string InstallSuffixes[] = { "/../../..", "/../../../..",
|
||||
"/../../../.." };
|
||||
const std::string Suffixes[] = {
|
||||
"/gcc/" + CandidateTriple.str(),
|
||||
"/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(),
|
||||
|
||||
// Ubuntu has a strange mis-matched pair of triples that this happens to
|
||||
// match.
|
||||
// FIXME: It may be worthwhile to generalize this and look for a second
|
||||
// triple.
|
||||
"/" + CandidateTriple.str() + "/gcc/i686-linux-gnu"
|
||||
};
|
||||
const std::string InstallSuffixes[] = {
|
||||
"/../../..",
|
||||
"/../../../..",
|
||||
"/../../../.."
|
||||
};
|
||||
// Only look at the final, weird Ubuntu suffix for i386-linux-gnu.
|
||||
const unsigned NumSuffixes = (llvm::array_lengthof(Suffixes) -
|
||||
(CandidateTriple != "i386-linux-gnu"));
|
||||
for (unsigned i = 0; i < NumSuffixes; ++i) {
|
||||
StringRef Suffix = Suffixes[i];
|
||||
llvm::error_code EC;
|
||||
for (llvm::sys::fs::directory_iterator LI(TripleDir + Suffix, EC), LE;
|
||||
for (llvm::sys::fs::directory_iterator LI(LibDir + Suffix, EC), LE;
|
||||
!EC && LI != LE; LI = LI.increment(EC)) {
|
||||
StringRef VersionText = llvm::sys::path::filename(LI->path());
|
||||
GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
|
||||
@@ -1730,7 +1730,7 @@ private:
|
||||
// FIXME: We hack together the directory name here instead of
|
||||
// using LI to ensure stable path separators across Windows and
|
||||
// Linux.
|
||||
GccInstallPath = TripleDir + Suffixes[i] + "/" + VersionText.str();
|
||||
GccInstallPath = LibDir + Suffixes[i] + "/" + VersionText.str();
|
||||
GccParentLibPath = GccInstallPath + InstallSuffixes[i];
|
||||
IsValid = true;
|
||||
}
|
||||
@@ -1744,6 +1744,41 @@ static void addPathIfExists(const std::string &Path,
|
||||
if (PathExists(Path)) Paths.push_back(Path);
|
||||
}
|
||||
|
||||
/// \brief Get our best guess at the multiarch triple for a target.
|
||||
///
|
||||
/// Debian-based systems are starting to use a multiarch setup where they use
|
||||
/// a target-triple directory in the library and header search paths.
|
||||
/// Unfortunately, this triple does not align with the vanilla target triple,
|
||||
/// so we provide a rough mapping here.
|
||||
static std::string getMultiarchTriple(const llvm::Triple TargetTriple,
|
||||
StringRef SysRoot) {
|
||||
// For most architectures, just use whatever we have rather than trying to be
|
||||
// clever.
|
||||
switch (TargetTriple.getArch()) {
|
||||
default:
|
||||
return TargetTriple.str();
|
||||
|
||||
// We use the existence of '/lib/<triple>' as a directory to detect some
|
||||
// common linux triples that don't quite match the Clang triple for both
|
||||
// 32-bit and 64-bit targets. This works around annoying discrepancies on
|
||||
// Debian-based systems.
|
||||
case llvm::Triple::x86:
|
||||
if (llvm::sys::fs::exists(SysRoot + "/lib/i686-linux-gnu"))
|
||||
return "i686-linux-gnu";
|
||||
if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu"))
|
||||
return "i386-linux-gnu";
|
||||
return TargetTriple.str();
|
||||
case llvm::Triple::x86_64:
|
||||
if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
|
||||
return "x86_64-linux-gnu";
|
||||
if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-pc-linux-gnu"))
|
||||
return "x86_64-pc-linux-gnu";
|
||||
if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-unknown-linux-gnu"))
|
||||
return "x86_64-unknown-linux-gnu";
|
||||
return TargetTriple.str();
|
||||
}
|
||||
}
|
||||
|
||||
Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
|
||||
: Generic_ELF(Host, Triple) {
|
||||
llvm::Triple::ArchType Arch =
|
||||
@@ -1804,6 +1839,7 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
|
||||
const std::string Suffix64 = Arch == llvm::Triple::x86_64 ? "" : "/64";
|
||||
const std::string Suffix = Is32Bits ? Suffix32 : Suffix64;
|
||||
const std::string Multilib = Is32Bits ? "lib32" : "lib64";
|
||||
const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot);
|
||||
|
||||
// FIXME: Because we add paths only when they exist on the system, I think we
|
||||
// should remove the concept of 'HasMultilib'. It's more likely to break the
|
||||
@@ -1821,26 +1857,35 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
|
||||
addPathIfExists(GCCInstallation.getInstallPath() + Suffix, Paths);
|
||||
addPathIfExists(LibPath + "/../" + GccTriple + "/lib/../" + Multilib,
|
||||
Paths);
|
||||
addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);
|
||||
addPathIfExists(LibPath + "/../" + Multilib, Paths);
|
||||
}
|
||||
addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
|
||||
addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths);
|
||||
addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
|
||||
addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths);
|
||||
|
||||
// Try walking via the GCC triple path in case of multiarch GCC
|
||||
// installations with strange symlinks.
|
||||
if (GCCInstallation.isValid())
|
||||
addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple() +
|
||||
"/../../" + Multilib, Paths);
|
||||
}
|
||||
|
||||
// Add the non-multiplib suffixed paths (if potentially different).
|
||||
// Add the non-multilib suffixed paths (if potentially different).
|
||||
if (GCCInstallation.isValid()) {
|
||||
const std::string &LibPath = GCCInstallation.getParentLibPath();
|
||||
const std::string &GccTriple = GCCInstallation.getTriple();
|
||||
if (!Suffix.empty() || !HasMultilib(Arch, Distro))
|
||||
addPathIfExists(GCCInstallation.getInstallPath(), Paths);
|
||||
addPathIfExists(LibPath + "/../" + GccTriple + "/lib", Paths);
|
||||
addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);
|
||||
addPathIfExists(LibPath, Paths);
|
||||
}
|
||||
addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
|
||||
addPathIfExists(SysRoot + "/lib", Paths);
|
||||
addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
|
||||
addPathIfExists(SysRoot + "/usr/lib", Paths);
|
||||
|
||||
if (GCCInstallation.isValid() && Arch == getArch() && IsUbuntu(Distro))
|
||||
Paths.push_back(SysRoot + "/usr/lib/" + GCCInstallation.getTriple());
|
||||
}
|
||||
|
||||
bool Linux::HasNativeLLVMSupport() const {
|
||||
|
||||
@@ -2026,6 +2026,23 @@ std::string CompilerInvocation::getModuleHash() const {
|
||||
Signature.add(getPreprocessorOpts().UsePredefines, 1);
|
||||
Signature.add(getPreprocessorOpts().DetailedRecord, 1);
|
||||
|
||||
// Hash the preprocessor defines.
|
||||
// FIXME: This is terrible. Use an MD5 sum of the preprocessor defines.
|
||||
std::vector<StringRef> MacroDefs;
|
||||
for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator
|
||||
I = getPreprocessorOpts().Macros.begin(),
|
||||
IEnd = getPreprocessorOpts().Macros.end();
|
||||
I != IEnd; ++I) {
|
||||
if (!I->second)
|
||||
MacroDefs.push_back(I->first);
|
||||
}
|
||||
llvm::array_pod_sort(MacroDefs.begin(), MacroDefs.end());
|
||||
|
||||
unsigned PPHashResult = 0;
|
||||
for (unsigned I = 0, N = MacroDefs.size(); I != N; ++I)
|
||||
PPHashResult = llvm::HashString(MacroDefs[I], PPHashResult);
|
||||
Signature.add(PPHashResult, 32);
|
||||
|
||||
// We've generated the signature. Treat it as one large APInt that we'll
|
||||
// encode in base-36 and return.
|
||||
Signature.flush();
|
||||
|
||||
@@ -566,6 +566,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
|
||||
AddPath("/usr/include/x86_64-linux-gnu/32", System, false, false, false);
|
||||
AddPath("/usr/include/i686-linux-gnu", System, false, false, false);
|
||||
AddPath("/usr/include/i486-linux-gnu", System, false, false, false);
|
||||
AddPath("/usr/include/i386-linux-gnu", System, false, false, false);
|
||||
} else if (triple.getArch() == llvm::Triple::arm) {
|
||||
AddPath("/usr/include/arm-linux-gnueabi", System, false, false, false);
|
||||
}
|
||||
|
||||
22
clang/test/CodeGen/pr9614.c
Normal file
22
clang/test/CodeGen/pr9614.c
Normal file
@@ -0,0 +1,22 @@
|
||||
// RUN: %clang_cc1 -emit-llvm %s -O1 -o - | FileCheck %s
|
||||
|
||||
extern void foo_alias (void) __asm ("foo");
|
||||
inline void foo (void) {
|
||||
return foo_alias ();
|
||||
}
|
||||
extern void bar_alias (void) __asm ("bar");
|
||||
inline __attribute__ ((__always_inline__)) void bar (void) {
|
||||
return bar_alias ();
|
||||
}
|
||||
void f(void) {
|
||||
foo();
|
||||
bar();
|
||||
}
|
||||
|
||||
// CHECK: define void @f()
|
||||
// CHECK: call void @foo()
|
||||
// CHECK-NEXT: call void @bar()
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
// CHECK: declare void @foo()
|
||||
// CHECK: declare void @bar()
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifdef FOO_RETURNS_INT_PTR
|
||||
int *foo(void);
|
||||
#else
|
||||
float *foo(void);
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -fno-objc-infer-related-result-type -Wmodule-build -fmodule-cache-path %t -F %S/Inputs -DFOO -verify %s
|
||||
// RUN: %clang_cc1 -fno-objc-infer-related-result-type -Wmodule-build -fmodule-cache-path %t -F %S/Inputs -verify %s
|
||||
|
||||
__import_module__ Module; // expected-warning{{building module 'Module' from source}}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -fno-objc-infer-related-result-type -Werror -fmodule-cache-path %t -F %S/Inputs -DFOO -verify %s
|
||||
// RUN: %clang_cc1 -fno-objc-infer-related-result-type -Werror -x objective-c++ -fmodule-cache-path %t -F %S/Inputs -DFOO -verify %s
|
||||
// RUN: %clang_cc1 -fno-objc-infer-related-result-type -Werror -fmodule-cache-path %t -F %S/Inputs -DFOO -verify %s
|
||||
|
||||
// RUN: %clang_cc1 -fno-objc-infer-related-result-type -Werror -fmodule-cache-path %t -F %S/Inputs -verify %s
|
||||
// RUN: %clang_cc1 -fno-objc-infer-related-result-type -Werror -x objective-c++ -fmodule-cache-path %t -F %S/Inputs -verify %s
|
||||
// RUN: %clang_cc1 -fno-objc-infer-related-result-type -Werror -fmodule-cache-path %t -F %S/Inputs -verify %s
|
||||
#define FOO
|
||||
__import_module__ Module;
|
||||
@interface OtherClass
|
||||
@end
|
||||
|
||||
13
clang/test/Modules/on-demand-macros.m
Normal file
13
clang/test/Modules/on-demand-macros.m
Normal file
@@ -0,0 +1,13 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -fmodule-cache-path %t -F %S/Inputs -DFOO_RETURNS_INT_PTR -verify %s
|
||||
// RUN: %clang_cc1 -fmodule-cache-path %t -F %S/Inputs -verify %s
|
||||
|
||||
__import_module__ CmdLine;
|
||||
|
||||
void test() {
|
||||
#ifdef FOO_RETURNS_INT_PTR
|
||||
int *ip = foo();
|
||||
#else
|
||||
float *fp = foo();
|
||||
#endif
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
|
||||
This is a collection of tests to check debugging information generated by
|
||||
compiler. This test suite can be checked out inside clang/test folder. This
|
||||
will enable 'make test' for clang to pick up these tests. Typically, test
|
||||
cases included here includes debugger commands and intended debugger output
|
||||
as comments in source file using DEBUGGER: and CHECK: as prefixes respectively.
|
||||
|
||||
For exmaple,
|
||||
|
||||
define i32 @f1(i32 %i) nounwind ssp {
|
||||
; DEBUGGER: break f1
|
||||
; DEBUGGER: r
|
||||
; DEBUGGER: p i
|
||||
; CHECK: $1 = 42
|
||||
entry:
|
||||
}
|
||||
|
||||
is a testcase where the debuger is asked to break at function 'f1' and
|
||||
print value of argument 'i'. The expected value of 'i' is 42 in this case.
|
||||
@@ -1,32 +0,0 @@
|
||||
// RUN: %clangxx -O0 -g %s -c -o %t.o
|
||||
// RUN: %clangxx %t.o -o %t.out
|
||||
// RUN: %test_debuginfo %s %t.out
|
||||
// Radar 8945514
|
||||
// DEBUGGER: break 22
|
||||
// DEBUGGER: r
|
||||
// DEBUGGER: p v
|
||||
// CHECK: $1 = (SVal &)
|
||||
// CHECK: Data = 0x0,
|
||||
// CHECK: Kind = 2142
|
||||
|
||||
class SVal {
|
||||
public:
|
||||
~SVal() {}
|
||||
const void* Data;
|
||||
unsigned Kind;
|
||||
};
|
||||
|
||||
void bar(SVal &v) {}
|
||||
class A {
|
||||
public:
|
||||
void foo(SVal v) { bar(v); }
|
||||
};
|
||||
|
||||
int main() {
|
||||
SVal v;
|
||||
v.Data = 0;
|
||||
v.Kind = 2142;
|
||||
A a;
|
||||
a.foo(v);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// RUN: %clang -O0 -g %s -c -o %t.o
|
||||
// RUN: %clang %t.o -o %t.out -framework Foundation
|
||||
// RUN: %test_debuginfo %s %t.out
|
||||
// XFAIL: *
|
||||
// XTARGET: darwin
|
||||
|
||||
// DEBUGGER: break 24
|
||||
// DEBUGGER: r
|
||||
// DEBUGGER: p result
|
||||
// CHECK: $1 = 42
|
||||
|
||||
void doBlock(void (^block)(void))
|
||||
{
|
||||
block();
|
||||
}
|
||||
|
||||
int I(int n)
|
||||
{
|
||||
__block int result;
|
||||
int i = 2;
|
||||
doBlock(^{
|
||||
result = n;
|
||||
});
|
||||
return result + i; /* Check value of 'result' */
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, const char * argv[]) {
|
||||
return I(42);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
// RUN: %clang -O0 -g %s -c -o %t.o
|
||||
// RUN: %clang %t.o -o %t.out -framework Foundation
|
||||
// RUN: %test_debuginfo %s %t.out
|
||||
// XFAIL: *
|
||||
// XTARGET: darwin
|
||||
// Radar 9279956
|
||||
|
||||
// DEBUGGER: break 31
|
||||
// DEBUGGER: r
|
||||
// DEBUGGER: p m2
|
||||
// DEBUGGER: p dbTransaction
|
||||
// DEBUGGER: p master
|
||||
// CHECK: $1 = 1
|
||||
// CHECK: $2 = 0
|
||||
// CHECK: $3 = 0
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
extern void foo(void(^)(void));
|
||||
|
||||
@interface A:NSObject @end
|
||||
@implementation A
|
||||
- (void) helper {
|
||||
int master = 0;
|
||||
__block int m2 = 0;
|
||||
__block int dbTransaction = 0;
|
||||
int (^x)(void) = ^(void) { (void) self;
|
||||
(void) master;
|
||||
(void) dbTransaction;
|
||||
m2++;
|
||||
return m2;
|
||||
};
|
||||
master = x();
|
||||
}
|
||||
@end
|
||||
|
||||
void foo(void(^x)(void)) {}
|
||||
|
||||
int main() {
|
||||
A *a = [A alloc];
|
||||
[a helper];
|
||||
return 0;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// RUN: %clangxx -O0 -g %s -c -o %t.o
|
||||
// RUN: %clangxx %t.o -o %t.out
|
||||
// RUN: %test_debuginfo %s %t.out
|
||||
|
||||
|
||||
// DEBUGGER: break 14
|
||||
// DEBUGGER: r
|
||||
// DEBUGGER: p *this
|
||||
// CHECK-NEXT-NOT: Cannot access memory at address
|
||||
|
||||
class A {
|
||||
public:
|
||||
A() : zero(0), data(42)
|
||||
{
|
||||
}
|
||||
private:
|
||||
int zero;
|
||||
int data;
|
||||
};
|
||||
|
||||
int main() {
|
||||
A a;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
; This test case checks debug info during register moves for an argument.
|
||||
; RUN: %clang -arch x86_64 -mllvm -fast-isel=false %s -c -o %t.o
|
||||
; RUN: %clang -arch x86_64 %t.o -o %t.out
|
||||
; RUN: %test_debuginfo %s %t.out
|
||||
; XFAIL: *
|
||||
; XTARGET: darwin
|
||||
; Radar 8412415
|
||||
|
||||
target triple = "x86_64-apple-darwin10.0.0"
|
||||
|
||||
%struct._mtx = type { i64, i32, %struct.anon }
|
||||
%struct.anon = type { i32, i32 }
|
||||
|
||||
define i32 @foobar(%struct._mtx* nocapture %mutex) nounwind readonly noinline ssp {
|
||||
; DEBUGGER: break foobar
|
||||
; DEBUGGER: r
|
||||
; DEBUGGER: info address mutex
|
||||
; CHECK: Symbol "mutex" is
|
||||
; CHECK-NEXT:
|
||||
; CHECK-NEXT: in register
|
||||
entry:
|
||||
tail call void @llvm.dbg.value(metadata !{%struct._mtx* %mutex}, i64 0, metadata !8), !dbg !29
|
||||
tail call void @llvm.dbg.value(metadata !30, i64 0, metadata !21), !dbg !31
|
||||
tail call void @llvm.dbg.value(metadata !32, i64 0, metadata !23), !dbg !33
|
||||
tail call void @llvm.dbg.value(metadata !32, i64 0, metadata !24), !dbg !34
|
||||
br label %do.body1, !dbg !37
|
||||
|
||||
do.body1: ; preds = %entry, %do.body1
|
||||
%0 = phi i32 [ 0, %entry ], [ %inc, %do.body1 ]
|
||||
%r.1 = phi i32 [ 1, %entry ], [ %r.0, %do.body1 ]
|
||||
%inc = add i32 %0, 1
|
||||
%tmp2 = getelementptr inbounds %struct._mtx* %mutex, i64 0, i32 1, !dbg !35
|
||||
%tmp3 = load i32* %tmp2, align 4, !dbg !35
|
||||
%tobool = icmp eq i32 %tmp3, 0, !dbg !35
|
||||
%r.0 = select i1 %tobool, i32 %r.1, i32 2
|
||||
%call = tail call i32 @bar(i32 %r.0, i32 %0), !dbg !38
|
||||
%cmp = icmp slt i32 %inc, %call, !dbg !39
|
||||
br i1 %cmp, label %do.body1, label %do.end9, !dbg !39
|
||||
|
||||
do.end9: ; preds = %do.body1
|
||||
tail call void @llvm.dbg.value(metadata !40, i64 0, metadata !21), !dbg !41
|
||||
tail call void @llvm.dbg.value(metadata !{i32 %call}, i64 0, metadata !24), !dbg !38
|
||||
tail call void @llvm.dbg.value(metadata !{i32 %inc}, i64 0, metadata !23), !dbg !42
|
||||
%add = add nsw i32 %r.0, %call, !dbg !43
|
||||
ret i32 %add, !dbg !43
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
|
||||
|
||||
define i32 @bar(i32 %i, i32 %j) nounwind readnone noinline ssp {
|
||||
entry:
|
||||
tail call void @llvm.dbg.value(metadata !{i32 %i}, i64 0, metadata !25), !dbg !44
|
||||
tail call void @llvm.dbg.value(metadata !{i32 %j}, i64 0, metadata !26), !dbg !45
|
||||
%add = add nsw i32 %j, %i, !dbg !46
|
||||
ret i32 %add, !dbg !46
|
||||
}
|
||||
|
||||
define i32 @main() nounwind readonly ssp {
|
||||
entry:
|
||||
%m = alloca %struct._mtx, align 8
|
||||
call void @llvm.dbg.declare(metadata !{%struct._mtx* %m}, metadata !27), !dbg !48
|
||||
%tmp = getelementptr inbounds %struct._mtx* %m, i64 0, i32 1, !dbg !49
|
||||
store i32 0, i32* %tmp, align 8, !dbg !49
|
||||
%call = call i32 @foobar(%struct._mtx* %m), !dbg !50
|
||||
ret i32 %call, !dbg !50
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
|
||||
|
||||
!llvm.dbg.sp = !{!0, !6, !7}
|
||||
!llvm.dbg.lv.foobar = !{!8, !21, !23, !24}
|
||||
!llvm.dbg.lv.bar = !{!25, !26}
|
||||
!llvm.dbg.lv.main = !{!27}
|
||||
|
||||
!0 = metadata !{i32 524334, i32 0, metadata !1, metadata !"foobar", metadata !"foobar", metadata !"foobar", metadata !1, i32 12, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, i32 (%struct._mtx*)* @foobar} ; [ DW_TAG_subprogram ]
|
||||
!1 = metadata !{i32 524329, metadata !"mu.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ]
|
||||
!2 = metadata !{i32 524305, i32 0, i32 12, metadata !"mu.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 114183)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
|
||||
!3 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ]
|
||||
!4 = metadata !{metadata !5}
|
||||
!5 = metadata !{i32 524324, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
|
||||
!6 = metadata !{i32 524334, i32 0, metadata !1, metadata !"bar", metadata !"bar", metadata !"bar", metadata !1, i32 26, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, i32 (i32, i32)* @bar} ; [ DW_TAG_subprogram ]
|
||||
!7 = metadata !{i32 524334, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata !1, i32 30, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, i32 ()* @main} ; [ DW_TAG_subprogram ]
|
||||
!8 = metadata !{i32 524545, metadata !0, metadata !"mutex", metadata !1, i32 12, metadata !9} ; [ DW_TAG_arg_variable ]
|
||||
!9 = metadata !{i32 524303, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !10} ; [ DW_TAG_pointer_type ]
|
||||
!10 = metadata !{i32 524310, metadata !1, metadata !"mtx_t", metadata !1, i32 9, i64 0, i64 0, i64 0, i32 0, metadata !11} ; [ DW_TAG_typedef ]
|
||||
!11 = metadata !{i32 524307, metadata !1, metadata !"_mtx", metadata !1, i32 2, i64 192, i64 64, i64 0, i32 0, null, metadata !12, i32 0, null} ; [ DW_TAG_structure_type ]
|
||||
!12 = metadata !{metadata !13, metadata !15, metadata !16}
|
||||
!13 = metadata !{i32 524301, metadata !1, metadata !"ptr", metadata !1, i32 3, i64 64, i64 64, i64 0, i32 0, metadata !14} ; [ DW_TAG_member ]
|
||||
!14 = metadata !{i32 524324, metadata !1, metadata !"long unsigned int", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ]
|
||||
!15 = metadata !{i32 524301, metadata !1, metadata !"waiters", metadata !1, i32 4, i64 32, i64 32, i64 64, i32 0, metadata !5} ; [ DW_TAG_member ]
|
||||
!16 = metadata !{i32 524301, metadata !1, metadata !"mtxi", metadata !1, i32 8, i64 64, i64 32, i64 96, i32 0, metadata !17} ; [ DW_TAG_member ]
|
||||
!17 = metadata !{i32 524307, metadata !11, metadata !"", metadata !1, i32 5, i64 64, i64 32, i64 0, i32 0, null, metadata !18, i32 0, null} ; [ DW_TAG_structure_type ]
|
||||
!18 = metadata !{metadata !19, metadata !20}
|
||||
!19 = metadata !{i32 524301, metadata !1, metadata !"tag", metadata !1, i32 6, i64 32, i64 32, i64 0, i32 0, metadata !5} ; [ DW_TAG_member ]
|
||||
!20 = metadata !{i32 524301, metadata !1, metadata !"pad", metadata !1, i32 7, i64 32, i64 32, i64 32, i32 0, metadata !5} ; [ DW_TAG_member ]
|
||||
!21 = metadata !{i32 524544, metadata !22, metadata !"r", metadata !1, i32 13, metadata !5} ; [ DW_TAG_auto_variable ]
|
||||
!22 = metadata !{i32 524299, metadata !0, i32 12, i32 52, metadata !1, i32 0} ; [ DW_TAG_lexical_block ]
|
||||
!23 = metadata !{i32 524544, metadata !22, metadata !"l", metadata !1, i32 14, metadata !5} ; [ DW_TAG_auto_variable ]
|
||||
!24 = metadata !{i32 524544, metadata !22, metadata !"j", metadata !1, i32 15, metadata !5} ; [ DW_TAG_auto_variable ]
|
||||
!25 = metadata !{i32 524545, metadata !6, metadata !"i", metadata !1, i32 26, metadata !5} ; [ DW_TAG_arg_variable ]
|
||||
!26 = metadata !{i32 524545, metadata !6, metadata !"j", metadata !1, i32 26, metadata !5} ; [ DW_TAG_arg_variable ]
|
||||
!27 = metadata !{i32 524544, metadata !28, metadata !"m", metadata !1, i32 31, metadata !10} ; [ DW_TAG_auto_variable ]
|
||||
!28 = metadata !{i32 524299, metadata !7, i32 30, i32 12, metadata !1, i32 4} ; [ DW_TAG_lexical_block ]
|
||||
!29 = metadata !{i32 12, i32 45, metadata !0, null}
|
||||
!30 = metadata !{i32 1}
|
||||
!31 = metadata !{i32 13, i32 12, metadata !22, null}
|
||||
!32 = metadata !{i32 0}
|
||||
!33 = metadata !{i32 14, i32 12, metadata !22, null}
|
||||
!34 = metadata !{i32 15, i32 12, metadata !22, null}
|
||||
!35 = metadata !{i32 18, i32 5, metadata !36, null}
|
||||
!36 = metadata !{i32 524299, metadata !22, i32 17, i32 6, metadata !1, i32 2} ; [ DW_TAG_lexical_block ]
|
||||
!37 = metadata !{i32 16, i32 3, metadata !22, null}
|
||||
!38 = metadata !{i32 20, i32 5, metadata !36, null}
|
||||
!39 = metadata !{i32 22, i32 3, metadata !36, null}
|
||||
!40 = metadata !{i32 2}
|
||||
!41 = metadata !{i32 19, i32 7, metadata !36, null}
|
||||
!42 = metadata !{i32 21, i32 5, metadata !36, null}
|
||||
!43 = metadata !{i32 23, i32 3, metadata !22, null}
|
||||
!44 = metadata !{i32 26, i32 39, metadata !6, null}
|
||||
!45 = metadata !{i32 26, i32 46, metadata !6, null}
|
||||
!46 = metadata !{i32 27, i32 3, metadata !47, null}
|
||||
!47 = metadata !{i32 524299, metadata !6, i32 26, i32 49, metadata !1, i32 3} ; [ DW_TAG_lexical_block ]
|
||||
!48 = metadata !{i32 31, i32 9, metadata !28, null}
|
||||
!49 = metadata !{i32 32, i32 3, metadata !28, null}
|
||||
!50 = metadata !{i32 33, i32 3, metadata !28, null}
|
||||
|
||||
@@ -1,263 +0,0 @@
|
||||
; This test case checks handling of llvm.dbg.declare intrinsic during fast-isel.
|
||||
; RUN: %clang -arch x86_64 -O0 -g %s -c -o %t.o
|
||||
; RUN: %clang -arch x86_64 %t.o -o %t.out
|
||||
; RUN: %test_debuginfo %s %t.out
|
||||
; XFAIL: *
|
||||
; XTARGET: darwin
|
||||
|
||||
target triple = "x86_64-apple-darwin"
|
||||
%struct.XYZ = type { i32, i32, i32, i32, i32 }
|
||||
|
||||
; Check handling of llvm.dbg.declare for an argument referred through alloca, where
|
||||
; alloca dominates llvm.dbg.declare
|
||||
define i32 @f1(i32 %i) nounwind ssp {
|
||||
; DEBUGGER: break f1
|
||||
; DEBUGGER: r
|
||||
; DEBUGGER: p i
|
||||
; CHECK: $1 = 42
|
||||
entry:
|
||||
%i.addr = alloca i32, align 4
|
||||
store i32 %i, i32* %i.addr, align 4
|
||||
call void @llvm.dbg.declare(metadata !{i32* %i.addr}, metadata !16), !dbg !17
|
||||
%tmp = load i32* %i.addr, align 4, !dbg !18
|
||||
ret i32 %tmp, !dbg !18
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
|
||||
|
||||
; Check handling of llvm.dbg.declare for an argument referred through alloca, where
|
||||
; llvm.dbg.declare dominates alloca.
|
||||
define i32 @f2(i32 %i) nounwind ssp {
|
||||
; DEBUGGER: break f2
|
||||
; DEBUGGER: c
|
||||
; DEBUGGER: p i
|
||||
; CHECK: $2 = 43
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{i32* %i.addr}, metadata !20), !dbg !21
|
||||
%i.addr = alloca i32, align 4
|
||||
store i32 %i, i32* %i.addr, align 4
|
||||
%tmp = load i32* %i.addr, align 4, !dbg !22
|
||||
ret i32 %tmp, !dbg !22
|
||||
}
|
||||
|
||||
; If llvm.dbg.declare is using an argument after its last use then register
|
||||
; allocator may destroy debug info for the argument. This is expected and
|
||||
; it should be fixed before registers are allocated.
|
||||
define i32 @f3(i32 %i) nounwind ssp {
|
||||
entry:
|
||||
%i.addr = alloca i32, align 4
|
||||
store i32 %i, i32* %i.addr, align 4
|
||||
call void @llvm.dbg.declare(metadata !{i32 %i}, metadata !24), !dbg !25
|
||||
%tmp = load i32* %i.addr, align 4, !dbg !26
|
||||
ret i32 %tmp, !dbg !26
|
||||
}
|
||||
|
||||
; Check handling of an argument referred directly by llvm.dbg.declare where
|
||||
; llvm.dbg.declare dominates all uses of argument.
|
||||
define i32 @f4(i32 %i) nounwind ssp {
|
||||
; DEBUGGER: break f4
|
||||
; DEBUGGER: c
|
||||
; DEBUGGER: p i
|
||||
; CHECK: $3 = 45
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{i32 %i}, metadata !28), !dbg !29
|
||||
ret i32 %i, !dbg !30
|
||||
}
|
||||
|
||||
; Check handling of an argument referred directly by llvm.dbg.declare where
|
||||
; llvm.dbg.declare dominates all uses of argument in separate basic block.
|
||||
define i32 @f5(i32 %i) nounwind ssp {
|
||||
; DEBUGGER: break f5
|
||||
; DEBUGGER: c
|
||||
; DEBUGGER: p i
|
||||
; CHECK: $4 = 46
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{i32 %i}, metadata !32), !dbg !33
|
||||
br label %bbr
|
||||
bbr:
|
||||
ret i32 %i, !dbg !34
|
||||
}
|
||||
|
||||
; Check handling of an argument referred directly by llvm.dbg.declare where
|
||||
; argument is not used.
|
||||
define i32 @f6(i32 %i) nounwind ssp {
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{i32 %i}, metadata !36), !dbg !37
|
||||
ret i32 1, !dbg !38
|
||||
}
|
||||
|
||||
; Check handling of an byval argument referred directly by llvm.dbg.declare where
|
||||
; argument is not used.
|
||||
define i32 @f7(%struct.XYZ* byval %i) nounwind ssp {
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{%struct.XYZ* %i}, metadata !40), !dbg !48
|
||||
ret i32 1, !dbg !49
|
||||
}
|
||||
|
||||
; Check handling of an byval argument referred directly by llvm.dbg.declare where
|
||||
; argument use dominates llvm.dbg.declare.
|
||||
define i32 @f8(%struct.XYZ* byval %i) nounwind ssp {
|
||||
; DEBUGGER: break f8
|
||||
; DEBUGGER: c
|
||||
; DEBUGGER: p i.x
|
||||
; CHECK: $5 = 51
|
||||
entry:
|
||||
%tmp = getelementptr inbounds %struct.XYZ* %i, i32 0, i32 1, !dbg !53
|
||||
%tmp1 = load i32* %tmp, align 4, !dbg !53
|
||||
call void @llvm.dbg.declare(metadata !{%struct.XYZ* %i}, metadata !51), !dbg !52
|
||||
ret i32 %tmp1, !dbg !53
|
||||
}
|
||||
|
||||
; Check handling of an byval argument referred directly by llvm.dbg.declare where
|
||||
; llvm.dbg.declare dominates all uses of argument.
|
||||
define i32 @f9(%struct.XYZ* byval %i) nounwind ssp {
|
||||
; DEBUGGER: break f9
|
||||
; DEBUGGER: c
|
||||
; DEBUGGER: p i.x
|
||||
; CHECK: $6 = 51
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{%struct.XYZ* %i}, metadata !55), !dbg !56
|
||||
%tmp = getelementptr inbounds %struct.XYZ* %i, i32 0, i32 2, !dbg !57
|
||||
%tmp1 = load i32* %tmp, align 4, !dbg !57
|
||||
ret i32 %tmp1, !dbg !57
|
||||
}
|
||||
|
||||
; Check handling of an byval argument referred directly by llvm.dbg.declare where
|
||||
; llvm.dbg.declare dominates all uses of argument in separate basic block.
|
||||
define i32 @f10(%struct.XYZ* byval %i) nounwind ssp {
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{%struct.XYZ* %i}, metadata !59), !dbg !60
|
||||
br label %bbr
|
||||
bbr:
|
||||
%tmp = getelementptr inbounds %struct.XYZ* %i, i32 0, i32 3, !dbg !61
|
||||
%tmp1 = load i32* %tmp, align 4, !dbg !61
|
||||
ret i32 %tmp1, !dbg !61
|
||||
}
|
||||
|
||||
define i32 @main() nounwind ssp {
|
||||
entry:
|
||||
%retval = alloca i32, align 4
|
||||
%abc = alloca %struct.XYZ, align 4
|
||||
%agg.tmp = alloca %struct.XYZ, align 4
|
||||
%agg.tmp13 = alloca %struct.XYZ, align 4
|
||||
%agg.tmp17 = alloca %struct.XYZ, align 4
|
||||
%agg.tmp21 = alloca %struct.XYZ, align 4
|
||||
store i32 0, i32* %retval
|
||||
%call = call i32 @f1(i32 42), !dbg !63
|
||||
%call1 = call i32 @f2(i32 43), !dbg !65
|
||||
%call2 = call i32 @f3(i32 44), !dbg !66
|
||||
%call3 = call i32 @f4(i32 45), !dbg !67
|
||||
%call4 = call i32 @f5(i32 46), !dbg !68
|
||||
%call5 = call i32 @f6(i32 47), !dbg !69
|
||||
call void @llvm.dbg.declare(metadata !{%struct.XYZ* %abc}, metadata !70), !dbg !71
|
||||
%tmp = getelementptr inbounds %struct.XYZ* %abc, i32 0, i32 0, !dbg !72
|
||||
store i32 51, i32* %tmp, align 4, !dbg !72
|
||||
%tmp6 = getelementptr inbounds %struct.XYZ* %abc, i32 0, i32 1, !dbg !72
|
||||
store i32 52, i32* %tmp6, align 4, !dbg !72
|
||||
%tmp7 = getelementptr inbounds %struct.XYZ* %abc, i32 0, i32 2, !dbg !72
|
||||
store i32 53, i32* %tmp7, align 4, !dbg !72
|
||||
%tmp8 = getelementptr inbounds %struct.XYZ* %abc, i32 0, i32 3, !dbg !72
|
||||
store i32 54, i32* %tmp8, align 4, !dbg !72
|
||||
%tmp9 = getelementptr inbounds %struct.XYZ* %abc, i32 0, i32 4, !dbg !72
|
||||
store i32 55, i32* %tmp9, align 4, !dbg !72
|
||||
%tmp10 = bitcast %struct.XYZ* %agg.tmp to i8*, !dbg !73
|
||||
%tmp11 = bitcast %struct.XYZ* %abc to i8*, !dbg !73
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp10, i8* %tmp11, i64 20, i32 4, i1 false), !dbg !73
|
||||
%call12 = call i32 @f7(%struct.XYZ* byval %agg.tmp), !dbg !73
|
||||
%tmp14 = bitcast %struct.XYZ* %agg.tmp13 to i8*, !dbg !74
|
||||
%tmp15 = bitcast %struct.XYZ* %abc to i8*, !dbg !74
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp14, i8* %tmp15, i64 20, i32 4, i1 false), !dbg !74
|
||||
%call16 = call i32 @f8(%struct.XYZ* byval %agg.tmp13), !dbg !74
|
||||
%tmp18 = bitcast %struct.XYZ* %agg.tmp17 to i8*, !dbg !75
|
||||
%tmp19 = bitcast %struct.XYZ* %abc to i8*, !dbg !75
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp18, i8* %tmp19, i64 20, i32 4, i1 false), !dbg !75
|
||||
%call20 = call i32 @f9(%struct.XYZ* byval %agg.tmp17), !dbg !75
|
||||
%tmp22 = bitcast %struct.XYZ* %agg.tmp21 to i8*, !dbg !76
|
||||
%tmp23 = bitcast %struct.XYZ* %abc to i8*, !dbg !76
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp22, i8* %tmp23, i64 20, i32 4, i1 false), !dbg !76
|
||||
%call24 = call i32 @f10(%struct.XYZ* byval %agg.tmp21), !dbg !76
|
||||
ret i32 0, !dbg !77
|
||||
}
|
||||
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
|
||||
|
||||
!llvm.dbg.sp = !{!0, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15}
|
||||
|
||||
!0 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f1", metadata !"f1", metadata !"f1", metadata !1, i32 11, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32)* @f1} ; [ DW_TAG_subprogram ]
|
||||
!1 = metadata !{i32 524329, metadata !"fastisel_arg.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ]
|
||||
!2 = metadata !{i32 524305, i32 0, i32 12, metadata !"fastisel_arg.c", metadata !"/private/tmp", metadata !"clang version 2.8 (trunk 112967)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
|
||||
!3 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ]
|
||||
!4 = metadata !{metadata !5}
|
||||
!5 = metadata !{i32 524324, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
|
||||
!6 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f2", metadata !"f2", metadata !"f2", metadata !1, i32 12, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32)* @f2} ; [ DW_TAG_subprogram ]
|
||||
!7 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f3", metadata !"f3", metadata !"f3", metadata !1, i32 13, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32)* @f3} ; [ DW_TAG_subprogram ]
|
||||
!8 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f4", metadata !"f4", metadata !"f4", metadata !1, i32 14, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32)* @f4} ; [ DW_TAG_subprogram ]
|
||||
!9 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f5", metadata !"f5", metadata !"f5", metadata !1, i32 15, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32)* @f5} ; [ DW_TAG_subprogram ]
|
||||
!10 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f6", metadata !"f6", metadata !"f6", metadata !1, i32 16, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32)* @f6} ; [ DW_TAG_subprogram ]
|
||||
!11 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f7", metadata !"f7", metadata !"f7", metadata !1, i32 17, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (%struct.XYZ*)* @f7} ; [ DW_TAG_subprogram ]
|
||||
!12 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f8", metadata !"f8", metadata !"f8", metadata !1, i32 18, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (%struct.XYZ*)* @f8} ; [ DW_TAG_subprogram ]
|
||||
!13 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f9", metadata !"f9", metadata !"f9", metadata !1, i32 19, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (%struct.XYZ*)* @f9} ; [ DW_TAG_subprogram ]
|
||||
!14 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f10", metadata !"f10", metadata !"f10", metadata !1, i32 20, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (%struct.XYZ*)* @f10} ; [ DW_TAG_subprogram ]
|
||||
!15 = metadata !{i32 524334, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata !1, i32 23, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ]
|
||||
!16 = metadata !{i32 524545, metadata !0, metadata !"i", metadata !1, i32 11, metadata !5} ; [ DW_TAG_arg_variable ]
|
||||
!17 = metadata !{i32 11, i32 12, metadata !0, null}
|
||||
!18 = metadata !{i32 11, i32 17, metadata !19, null}
|
||||
!19 = metadata !{i32 524299, metadata !0, i32 11, i32 15, metadata !1, i32 0} ; [ DW_TAG_lexical_block ]
|
||||
!20 = metadata !{i32 524545, metadata !6, metadata !"i", metadata !1, i32 12, metadata !5} ; [ DW_TAG_arg_variable ]
|
||||
!21 = metadata !{i32 12, i32 12, metadata !6, null}
|
||||
!22 = metadata !{i32 12, i32 17, metadata !23, null}
|
||||
!23 = metadata !{i32 524299, metadata !6, i32 12, i32 15, metadata !1, i32 1} ; [ DW_TAG_lexical_block ]
|
||||
!24 = metadata !{i32 524545, metadata !7, metadata !"i", metadata !1, i32 13, metadata !5} ; [ DW_TAG_arg_variable ]
|
||||
!25 = metadata !{i32 13, i32 12, metadata !7, null}
|
||||
!26 = metadata !{i32 13, i32 17, metadata !27, null}
|
||||
!27 = metadata !{i32 524299, metadata !7, i32 13, i32 15, metadata !1, i32 2} ; [ DW_TAG_lexical_block ]
|
||||
!28 = metadata !{i32 524545, metadata !8, metadata !"i", metadata !1, i32 14, metadata !5} ; [ DW_TAG_arg_variable ]
|
||||
!29 = metadata !{i32 14, i32 12, metadata !8, null}
|
||||
!30 = metadata !{i32 14, i32 17, metadata !31, null}
|
||||
!31 = metadata !{i32 524299, metadata !8, i32 14, i32 15, metadata !1, i32 3} ; [ DW_TAG_lexical_block ]
|
||||
!32 = metadata !{i32 524545, metadata !9, metadata !"i", metadata !1, i32 15, metadata !5} ; [ DW_TAG_arg_variable ]
|
||||
!33 = metadata !{i32 15, i32 12, metadata !9, null}
|
||||
!34 = metadata !{i32 15, i32 17, metadata !35, null}
|
||||
!35 = metadata !{i32 524299, metadata !9, i32 15, i32 15, metadata !1, i32 4} ; [ DW_TAG_lexical_block ]
|
||||
!36 = metadata !{i32 524545, metadata !10, metadata !"i", metadata !1, i32 16, metadata !5} ; [ DW_TAG_arg_variable ]
|
||||
!37 = metadata !{i32 16, i32 12, metadata !10, null}
|
||||
!38 = metadata !{i32 16, i32 17, metadata !39, null}
|
||||
!39 = metadata !{i32 524299, metadata !10, i32 16, i32 15, metadata !1, i32 5} ; [ DW_TAG_lexical_block ]
|
||||
!40 = metadata !{i32 524545, metadata !11, metadata !"i", metadata !1, i32 17, metadata !41} ; [ DW_TAG_arg_variable ]
|
||||
!41 = metadata !{i32 524307, metadata !1, metadata !"XYZ", metadata !1, i32 2, i64 160, i64 32, i64 0, i32 0, null, metadata !42, i32 0, null} ; [ DW_TAG_structure_type ]
|
||||
!42 = metadata !{metadata !43, metadata !44, metadata !45, metadata !46, metadata !47}
|
||||
!43 = metadata !{i32 524301, metadata !1, metadata !"x", metadata !1, i32 3, i64 32, i64 32, i64 0, i32 0, metadata !5} ; [ DW_TAG_member ]
|
||||
!44 = metadata !{i32 524301, metadata !1, metadata !"y", metadata !1, i32 4, i64 32, i64 32, i64 32, i32 0, metadata !5} ; [ DW_TAG_member ]
|
||||
!45 = metadata !{i32 524301, metadata !1, metadata !"z", metadata !1, i32 5, i64 32, i64 32, i64 64, i32 0, metadata !5} ; [ DW_TAG_member ]
|
||||
!46 = metadata !{i32 524301, metadata !1, metadata !"a", metadata !1, i32 6, i64 32, i64 32, i64 96, i32 0, metadata !5} ; [ DW_TAG_member ]
|
||||
!47 = metadata !{i32 524301, metadata !1, metadata !"b", metadata !1, i32 7, i64 32, i64 32, i64 128, i32 0, metadata !5} ; [ DW_TAG_member ]
|
||||
!48 = metadata !{i32 17, i32 19, metadata !11, null}
|
||||
!49 = metadata !{i32 17, i32 24, metadata !50, null}
|
||||
!50 = metadata !{i32 524299, metadata !11, i32 17, i32 22, metadata !1, i32 6} ; [ DW_TAG_lexical_block ]
|
||||
!51 = metadata !{i32 524545, metadata !12, metadata !"i", metadata !1, i32 18, metadata !41} ; [ DW_TAG_arg_variable ]
|
||||
!52 = metadata !{i32 18, i32 19, metadata !12, null}
|
||||
!53 = metadata !{i32 18, i32 24, metadata !54, null}
|
||||
!54 = metadata !{i32 524299, metadata !12, i32 18, i32 22, metadata !1, i32 7} ; [ DW_TAG_lexical_block ]
|
||||
!55 = metadata !{i32 524545, metadata !13, metadata !"i", metadata !1, i32 19, metadata !41} ; [ DW_TAG_arg_variable ]
|
||||
!56 = metadata !{i32 19, i32 19, metadata !13, null}
|
||||
!57 = metadata !{i32 19, i32 24, metadata !58, null}
|
||||
!58 = metadata !{i32 524299, metadata !13, i32 19, i32 22, metadata !1, i32 8} ; [ DW_TAG_lexical_block ]
|
||||
!59 = metadata !{i32 524545, metadata !14, metadata !"i", metadata !1, i32 20, metadata !41} ; [ DW_TAG_arg_variable ]
|
||||
!60 = metadata !{i32 20, i32 20, metadata !14, null}
|
||||
!61 = metadata !{i32 20, i32 25, metadata !62, null}
|
||||
!62 = metadata !{i32 524299, metadata !14, i32 20, i32 23, metadata !1, i32 9} ; [ DW_TAG_lexical_block ]
|
||||
!63 = metadata !{i32 24, i32 3, metadata !64, null}
|
||||
!64 = metadata !{i32 524299, metadata !15, i32 23, i32 12, metadata !1, i32 10} ; [ DW_TAG_lexical_block ]
|
||||
!65 = metadata !{i32 25, i32 3, metadata !64, null}
|
||||
!66 = metadata !{i32 26, i32 3, metadata !64, null}
|
||||
!67 = metadata !{i32 27, i32 3, metadata !64, null}
|
||||
!68 = metadata !{i32 28, i32 3, metadata !64, null}
|
||||
!69 = metadata !{i32 29, i32 3, metadata !64, null}
|
||||
!70 = metadata !{i32 524544, metadata !64, metadata !"abc", metadata !1, i32 30, metadata !41} ; [ DW_TAG_auto_variable ]
|
||||
!71 = metadata !{i32 30, i32 14, metadata !64, null}
|
||||
!72 = metadata !{i32 30, i32 17, metadata !64, null}
|
||||
!73 = metadata !{i32 31, i32 3, metadata !64, null}
|
||||
!74 = metadata !{i32 32, i32 3, metadata !64, null}
|
||||
!75 = metadata !{i32 33, i32 3, metadata !64, null}
|
||||
!76 = metadata !{i32 34, i32 3, metadata !64, null}
|
||||
!77 = metadata !{i32 36, i32 3, metadata !64, null}
|
||||
@@ -1,264 +0,0 @@
|
||||
; This test case checks handling of llvm.dbg.declare intrinsic during isel.
|
||||
; RUN: %clang -arch x86_64 -mllvm -fast-isel=false -mllvm -regalloc=default -g %s -c -o %t.o
|
||||
; RUN: %clang -arch x86_64 %t.o -o %t.out
|
||||
; RUN: %test_debuginfo %s %t.out
|
||||
; XFAIL: *
|
||||
; XTARGET: darwin
|
||||
|
||||
target triple = "x86_64-apple-darwin"
|
||||
%struct.XYZ = type { i32, i32, i32, i32, i32 }
|
||||
|
||||
; Check handling of llvm.dbg.declare for an argument referred through alloca, where
|
||||
; alloca dominates llvm.dbg.declare
|
||||
define i32 @f1(i32 %i) nounwind ssp {
|
||||
; DEBUGGER: break f1
|
||||
; DEBUGGER: r
|
||||
; DEBUGGER: p i
|
||||
; CHECK: $1 = 42
|
||||
entry:
|
||||
%i.addr = alloca i32, align 4
|
||||
store i32 %i, i32* %i.addr, align 4
|
||||
call void @llvm.dbg.declare(metadata !{i32* %i.addr}, metadata !16), !dbg !17
|
||||
%tmp = load i32* %i.addr, align 4, !dbg !18
|
||||
ret i32 %tmp, !dbg !18
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
|
||||
|
||||
; Check handling of llvm.dbg.declare for an argument referred through alloca, where
|
||||
; llvm.dbg.declare dominates alloca.
|
||||
define i32 @f2(i32 %i) nounwind ssp {
|
||||
; DEBUGGER: break f2
|
||||
; DEBUGGER: c
|
||||
; DEBUGGER: p i
|
||||
; CHECK: $2 = 43
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{i32* %i.addr}, metadata !20), !dbg !21
|
||||
%i.addr = alloca i32, align 4
|
||||
store i32 %i, i32* %i.addr, align 4
|
||||
%tmp = load i32* %i.addr, align 4, !dbg !22
|
||||
ret i32 %tmp, !dbg !22
|
||||
}
|
||||
|
||||
; Check handling of an argument referred directly by llvm.dbg.declare where at least
|
||||
; one argument use dominates llvm.dbg.declare.
|
||||
; This is expected to not work because registor allocator has freedom to kill 'i'
|
||||
; after its last use.
|
||||
define i32 @f3(i32 %i) nounwind ssp {
|
||||
entry:
|
||||
%i.addr = alloca i32, align 4
|
||||
store i32 %i, i32* %i.addr, align 4
|
||||
call void @llvm.dbg.declare(metadata !{i32 %i}, metadata !24), !dbg !25
|
||||
%tmp = load i32* %i.addr, align 4, !dbg !26
|
||||
ret i32 %tmp, !dbg !26
|
||||
}
|
||||
|
||||
; Check handling of an argument referred directly by llvm.dbg.declare where
|
||||
; llvm.dbg.declare dominates all uses of argument.
|
||||
define i32 @f4(i32 %i) nounwind ssp {
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{i32 %i}, metadata !28), !dbg !29
|
||||
ret i32 %i, !dbg !30
|
||||
}
|
||||
|
||||
; Check handling of an argument referred directly by llvm.dbg.declare where
|
||||
; llvm.dbg.declare dominates all uses of argument in separate basic block.
|
||||
define i32 @f5(i32 %i) nounwind ssp {
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{i32 %i}, metadata !32), !dbg !33
|
||||
br label %bbr
|
||||
bbr:
|
||||
ret i32 %i, !dbg !34
|
||||
}
|
||||
|
||||
; Check handling of an argument referred directly by llvm.dbg.declare where
|
||||
; argument is not used.
|
||||
define i32 @f6(i32 %i) nounwind ssp {
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{i32 %i}, metadata !36), !dbg !37
|
||||
ret i32 1, !dbg !38
|
||||
}
|
||||
|
||||
; Check handling of an byval argument referred directly by llvm.dbg.declare where
|
||||
; argument is not used.
|
||||
define i32 @f7(%struct.XYZ* byval %i) nounwind ssp {
|
||||
; DEBUGGER: break f7
|
||||
; DEBUGGER: c
|
||||
; DEBUGGER: p i.x
|
||||
; CHECK: $3 = 51
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{%struct.XYZ* %i}, metadata !40), !dbg !48
|
||||
ret i32 1, !dbg !49
|
||||
}
|
||||
|
||||
; Check handling of an byval argument referred directly by llvm.dbg.declare where
|
||||
; argument use dominates llvm.dbg.declare.
|
||||
define i32 @f8(%struct.XYZ* byval %i) nounwind ssp {
|
||||
; DEBUGGER: break f8
|
||||
; DEBUGGER: c
|
||||
; DEBUGGER: p i.x
|
||||
; CHECK: $4 = 51
|
||||
entry:
|
||||
%tmp = getelementptr inbounds %struct.XYZ* %i, i32 0, i32 1, !dbg !53
|
||||
%tmp1 = load i32* %tmp, align 4, !dbg !53
|
||||
call void @llvm.dbg.declare(metadata !{%struct.XYZ* %i}, metadata !51), !dbg !52
|
||||
ret i32 %tmp1, !dbg !53
|
||||
}
|
||||
|
||||
; Check handling of an byval argument referred directly by llvm.dbg.declare where
|
||||
; llvm.dbg.declare dominates all uses of argument.
|
||||
define i32 @f9(%struct.XYZ* byval %i) nounwind ssp {
|
||||
; DEBUGGER: break f9
|
||||
; DEBUGGER: c
|
||||
; DEBUGGER: p i.x
|
||||
; CHECK: $5 = 51
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{%struct.XYZ* %i}, metadata !55), !dbg !56
|
||||
%tmp = getelementptr inbounds %struct.XYZ* %i, i32 0, i32 2, !dbg !57
|
||||
%tmp1 = load i32* %tmp, align 4, !dbg !57
|
||||
ret i32 %tmp1, !dbg !57
|
||||
}
|
||||
|
||||
; Check handling of an byval argument referred directly by llvm.dbg.declare where
|
||||
; llvm.dbg.declare dominates all uses of argument in separate basic block.
|
||||
define i32 @f10(%struct.XYZ* byval %i) nounwind ssp {
|
||||
; DEBUGGER: break f10
|
||||
; DEBUGGER: c
|
||||
; DEBUGGER: p i.x
|
||||
; CHECK: $6 = 51
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{%struct.XYZ* %i}, metadata !59), !dbg !60
|
||||
br label %bbr
|
||||
bbr:
|
||||
%tmp = getelementptr inbounds %struct.XYZ* %i, i32 0, i32 3, !dbg !61
|
||||
%tmp1 = load i32* %tmp, align 4, !dbg !61
|
||||
ret i32 %tmp1, !dbg !61
|
||||
}
|
||||
|
||||
define i32 @main() nounwind ssp {
|
||||
entry:
|
||||
%retval = alloca i32, align 4
|
||||
%abc = alloca %struct.XYZ, align 4
|
||||
%agg.tmp = alloca %struct.XYZ, align 4
|
||||
%agg.tmp13 = alloca %struct.XYZ, align 4
|
||||
%agg.tmp17 = alloca %struct.XYZ, align 4
|
||||
%agg.tmp21 = alloca %struct.XYZ, align 4
|
||||
store i32 0, i32* %retval
|
||||
%call = call i32 @f1(i32 42), !dbg !63
|
||||
%call1 = call i32 @f2(i32 43), !dbg !65
|
||||
%call2 = call i32 @f3(i32 44), !dbg !66
|
||||
%call3 = call i32 @f4(i32 45), !dbg !67
|
||||
%call4 = call i32 @f5(i32 46), !dbg !68
|
||||
%call5 = call i32 @f6(i32 47), !dbg !69
|
||||
call void @llvm.dbg.declare(metadata !{%struct.XYZ* %abc}, metadata !70), !dbg !71
|
||||
%tmp = getelementptr inbounds %struct.XYZ* %abc, i32 0, i32 0, !dbg !72
|
||||
store i32 51, i32* %tmp, align 4, !dbg !72
|
||||
%tmp6 = getelementptr inbounds %struct.XYZ* %abc, i32 0, i32 1, !dbg !72
|
||||
store i32 52, i32* %tmp6, align 4, !dbg !72
|
||||
%tmp7 = getelementptr inbounds %struct.XYZ* %abc, i32 0, i32 2, !dbg !72
|
||||
store i32 53, i32* %tmp7, align 4, !dbg !72
|
||||
%tmp8 = getelementptr inbounds %struct.XYZ* %abc, i32 0, i32 3, !dbg !72
|
||||
store i32 54, i32* %tmp8, align 4, !dbg !72
|
||||
%tmp9 = getelementptr inbounds %struct.XYZ* %abc, i32 0, i32 4, !dbg !72
|
||||
store i32 55, i32* %tmp9, align 4, !dbg !72
|
||||
%tmp10 = bitcast %struct.XYZ* %agg.tmp to i8*, !dbg !73
|
||||
%tmp11 = bitcast %struct.XYZ* %abc to i8*, !dbg !73
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp10, i8* %tmp11, i64 20, i32 4, i1 false), !dbg !73
|
||||
%call12 = call i32 @f7(%struct.XYZ* byval %agg.tmp), !dbg !73
|
||||
%tmp14 = bitcast %struct.XYZ* %agg.tmp13 to i8*, !dbg !74
|
||||
%tmp15 = bitcast %struct.XYZ* %abc to i8*, !dbg !74
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp14, i8* %tmp15, i64 20, i32 4, i1 false), !dbg !74
|
||||
%call16 = call i32 @f8(%struct.XYZ* byval %agg.tmp13), !dbg !74
|
||||
%tmp18 = bitcast %struct.XYZ* %agg.tmp17 to i8*, !dbg !75
|
||||
%tmp19 = bitcast %struct.XYZ* %abc to i8*, !dbg !75
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp18, i8* %tmp19, i64 20, i32 4, i1 false), !dbg !75
|
||||
%call20 = call i32 @f9(%struct.XYZ* byval %agg.tmp17), !dbg !75
|
||||
%tmp22 = bitcast %struct.XYZ* %agg.tmp21 to i8*, !dbg !76
|
||||
%tmp23 = bitcast %struct.XYZ* %abc to i8*, !dbg !76
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp22, i8* %tmp23, i64 20, i32 4, i1 false), !dbg !76
|
||||
%call24 = call i32 @f10(%struct.XYZ* byval %agg.tmp21), !dbg !76
|
||||
ret i32 0, !dbg !77
|
||||
}
|
||||
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
|
||||
|
||||
!llvm.dbg.sp = !{!0, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15}
|
||||
|
||||
!0 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f1", metadata !"f1", metadata !"f1", metadata !1, i32 11, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32)* @f1} ; [ DW_TAG_subprogram ]
|
||||
!1 = metadata !{i32 524329, metadata !"fastisel_arg.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ]
|
||||
!2 = metadata !{i32 524305, i32 0, i32 12, metadata !"fastisel_arg.c", metadata !"/private/tmp", metadata !"clang version 2.8 (trunk 112967)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
|
||||
!3 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ]
|
||||
!4 = metadata !{metadata !5}
|
||||
!5 = metadata !{i32 524324, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
|
||||
!6 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f2", metadata !"f2", metadata !"f2", metadata !1, i32 12, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32)* @f2} ; [ DW_TAG_subprogram ]
|
||||
!7 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f3", metadata !"f3", metadata !"f3", metadata !1, i32 13, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32)* @f3} ; [ DW_TAG_subprogram ]
|
||||
!8 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f4", metadata !"f4", metadata !"f4", metadata !1, i32 14, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32)* @f4} ; [ DW_TAG_subprogram ]
|
||||
!9 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f5", metadata !"f5", metadata !"f5", metadata !1, i32 15, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32)* @f5} ; [ DW_TAG_subprogram ]
|
||||
!10 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f6", metadata !"f6", metadata !"f6", metadata !1, i32 16, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32)* @f6} ; [ DW_TAG_subprogram ]
|
||||
!11 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f7", metadata !"f7", metadata !"f7", metadata !1, i32 17, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (%struct.XYZ*)* @f7} ; [ DW_TAG_subprogram ]
|
||||
!12 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f8", metadata !"f8", metadata !"f8", metadata !1, i32 18, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (%struct.XYZ*)* @f8} ; [ DW_TAG_subprogram ]
|
||||
!13 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f9", metadata !"f9", metadata !"f9", metadata !1, i32 19, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (%struct.XYZ*)* @f9} ; [ DW_TAG_subprogram ]
|
||||
!14 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f10", metadata !"f10", metadata !"f10", metadata !1, i32 20, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (%struct.XYZ*)* @f10} ; [ DW_TAG_subprogram ]
|
||||
!15 = metadata !{i32 524334, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata !1, i32 23, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ]
|
||||
!16 = metadata !{i32 524545, metadata !0, metadata !"i", metadata !1, i32 11, metadata !5} ; [ DW_TAG_arg_variable ]
|
||||
!17 = metadata !{i32 11, i32 12, metadata !0, null}
|
||||
!18 = metadata !{i32 11, i32 17, metadata !19, null}
|
||||
!19 = metadata !{i32 524299, metadata !0, i32 11, i32 15, metadata !1, i32 0} ; [ DW_TAG_lexical_block ]
|
||||
!20 = metadata !{i32 524545, metadata !6, metadata !"i", metadata !1, i32 12, metadata !5} ; [ DW_TAG_arg_variable ]
|
||||
!21 = metadata !{i32 12, i32 12, metadata !6, null}
|
||||
!22 = metadata !{i32 12, i32 17, metadata !23, null}
|
||||
!23 = metadata !{i32 524299, metadata !6, i32 12, i32 15, metadata !1, i32 1} ; [ DW_TAG_lexical_block ]
|
||||
!24 = metadata !{i32 524545, metadata !7, metadata !"i", metadata !1, i32 13, metadata !5} ; [ DW_TAG_arg_variable ]
|
||||
!25 = metadata !{i32 13, i32 12, metadata !7, null}
|
||||
!26 = metadata !{i32 13, i32 17, metadata !27, null}
|
||||
!27 = metadata !{i32 524299, metadata !7, i32 13, i32 15, metadata !1, i32 2} ; [ DW_TAG_lexical_block ]
|
||||
!28 = metadata !{i32 524545, metadata !8, metadata !"i", metadata !1, i32 14, metadata !5} ; [ DW_TAG_arg_variable ]
|
||||
!29 = metadata !{i32 14, i32 12, metadata !8, null}
|
||||
!30 = metadata !{i32 14, i32 17, metadata !31, null}
|
||||
!31 = metadata !{i32 524299, metadata !8, i32 14, i32 15, metadata !1, i32 3} ; [ DW_TAG_lexical_block ]
|
||||
!32 = metadata !{i32 524545, metadata !9, metadata !"i", metadata !1, i32 15, metadata !5} ; [ DW_TAG_arg_variable ]
|
||||
!33 = metadata !{i32 15, i32 12, metadata !9, null}
|
||||
!34 = metadata !{i32 15, i32 17, metadata !35, null}
|
||||
!35 = metadata !{i32 524299, metadata !9, i32 15, i32 15, metadata !1, i32 4} ; [ DW_TAG_lexical_block ]
|
||||
!36 = metadata !{i32 524545, metadata !10, metadata !"i", metadata !1, i32 16, metadata !5} ; [ DW_TAG_arg_variable ]
|
||||
!37 = metadata !{i32 16, i32 12, metadata !10, null}
|
||||
!38 = metadata !{i32 16, i32 17, metadata !39, null}
|
||||
!39 = metadata !{i32 524299, metadata !10, i32 16, i32 15, metadata !1, i32 5} ; [ DW_TAG_lexical_block ]
|
||||
!40 = metadata !{i32 524545, metadata !11, metadata !"i", metadata !1, i32 17, metadata !41} ; [ DW_TAG_arg_variable ]
|
||||
!41 = metadata !{i32 524307, metadata !1, metadata !"XYZ", metadata !1, i32 2, i64 160, i64 32, i64 0, i32 0, null, metadata !42, i32 0, null} ; [ DW_TAG_structure_type ]
|
||||
!42 = metadata !{metadata !43, metadata !44, metadata !45, metadata !46, metadata !47}
|
||||
!43 = metadata !{i32 524301, metadata !1, metadata !"x", metadata !1, i32 3, i64 32, i64 32, i64 0, i32 0, metadata !5} ; [ DW_TAG_member ]
|
||||
!44 = metadata !{i32 524301, metadata !1, metadata !"y", metadata !1, i32 4, i64 32, i64 32, i64 32, i32 0, metadata !5} ; [ DW_TAG_member ]
|
||||
!45 = metadata !{i32 524301, metadata !1, metadata !"z", metadata !1, i32 5, i64 32, i64 32, i64 64, i32 0, metadata !5} ; [ DW_TAG_member ]
|
||||
!46 = metadata !{i32 524301, metadata !1, metadata !"a", metadata !1, i32 6, i64 32, i64 32, i64 96, i32 0, metadata !5} ; [ DW_TAG_member ]
|
||||
!47 = metadata !{i32 524301, metadata !1, metadata !"b", metadata !1, i32 7, i64 32, i64 32, i64 128, i32 0, metadata !5} ; [ DW_TAG_member ]
|
||||
!48 = metadata !{i32 17, i32 19, metadata !11, null}
|
||||
!49 = metadata !{i32 17, i32 24, metadata !50, null}
|
||||
!50 = metadata !{i32 524299, metadata !11, i32 17, i32 22, metadata !1, i32 6} ; [ DW_TAG_lexical_block ]
|
||||
!51 = metadata !{i32 524545, metadata !12, metadata !"i", metadata !1, i32 18, metadata !41} ; [ DW_TAG_arg_variable ]
|
||||
!52 = metadata !{i32 18, i32 19, metadata !12, null}
|
||||
!53 = metadata !{i32 18, i32 24, metadata !54, null}
|
||||
!54 = metadata !{i32 524299, metadata !12, i32 18, i32 22, metadata !1, i32 7} ; [ DW_TAG_lexical_block ]
|
||||
!55 = metadata !{i32 524545, metadata !13, metadata !"i", metadata !1, i32 19, metadata !41} ; [ DW_TAG_arg_variable ]
|
||||
!56 = metadata !{i32 19, i32 19, metadata !13, null}
|
||||
!57 = metadata !{i32 19, i32 24, metadata !58, null}
|
||||
!58 = metadata !{i32 524299, metadata !13, i32 19, i32 22, metadata !1, i32 8} ; [ DW_TAG_lexical_block ]
|
||||
!59 = metadata !{i32 524545, metadata !14, metadata !"i", metadata !1, i32 20, metadata !41} ; [ DW_TAG_arg_variable ]
|
||||
!60 = metadata !{i32 20, i32 20, metadata !14, null}
|
||||
!61 = metadata !{i32 20, i32 25, metadata !62, null}
|
||||
!62 = metadata !{i32 524299, metadata !14, i32 20, i32 23, metadata !1, i32 9} ; [ DW_TAG_lexical_block ]
|
||||
!63 = metadata !{i32 24, i32 3, metadata !64, null}
|
||||
!64 = metadata !{i32 524299, metadata !15, i32 23, i32 12, metadata !1, i32 10} ; [ DW_TAG_lexical_block ]
|
||||
!65 = metadata !{i32 25, i32 3, metadata !64, null}
|
||||
!66 = metadata !{i32 26, i32 3, metadata !64, null}
|
||||
!67 = metadata !{i32 27, i32 3, metadata !64, null}
|
||||
!68 = metadata !{i32 28, i32 3, metadata !64, null}
|
||||
!69 = metadata !{i32 29, i32 3, metadata !64, null}
|
||||
!70 = metadata !{i32 524544, metadata !64, metadata !"abc", metadata !1, i32 30, metadata !41} ; [ DW_TAG_auto_variable ]
|
||||
!71 = metadata !{i32 30, i32 14, metadata !64, null}
|
||||
!72 = metadata !{i32 30, i32 17, metadata !64, null}
|
||||
!73 = metadata !{i32 31, i32 3, metadata !64, null}
|
||||
!74 = metadata !{i32 32, i32 3, metadata !64, null}
|
||||
!75 = metadata !{i32 33, i32 3, metadata !64, null}
|
||||
!76 = metadata !{i32 34, i32 3, metadata !64, null}
|
||||
!77 = metadata !{i32 36, i32 3, metadata !64, null}
|
||||
@@ -1,31 +0,0 @@
|
||||
// RUN: %clang -O0 -g %s -c -o %t.o
|
||||
// RUN: %clang %t.o -o %t.out -framework Foundation
|
||||
// RUN: %test_debuginfo %s %t.out
|
||||
// XFAIL: *
|
||||
// XTARGET: darwin
|
||||
// Radar 8757124
|
||||
|
||||
// DEBUGGER: break 25
|
||||
// DEBUGGER: r
|
||||
// DEBUGGER: po thing
|
||||
// CHECK: aaa
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
int main (int argc, const char * argv[]) {
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSArray *things = [NSArray arrayWithObjects:@"one", @"two", @"three" , nil];
|
||||
for (NSString *thing in things) {
|
||||
NSLog (@"%@", thing);
|
||||
}
|
||||
|
||||
things = [NSArray arrayWithObjects:@"aaa", @"bbb", @"ccc" , nil];
|
||||
for (NSString *thing in things) {
|
||||
NSLog (@"%@", thing);
|
||||
}
|
||||
[pool release];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// RUN: %clangxx -O0 -g %s -c -o %t.o
|
||||
// RUN: %test_debuginfo %s %t.o
|
||||
// Radar 9168773
|
||||
|
||||
// DEBUGGER: ptype A
|
||||
// CHECK: type = class A {
|
||||
// CHECK-NEXT: public:
|
||||
// CHECK-NEXT: int MyData;
|
||||
// CHECK-NEXT: }
|
||||
class A;
|
||||
class B {
|
||||
public:
|
||||
void foo(const A *p);
|
||||
};
|
||||
|
||||
B iEntry;
|
||||
|
||||
class A {
|
||||
public:
|
||||
int MyData;
|
||||
};
|
||||
|
||||
A irp;
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
; This test case checks handling of llvm.dbg.declare intrinsic during fast-isel.
|
||||
; RUN: %clang -arch x86_64 -O0 -g %s -c -o %t.o
|
||||
; RUN: %clang -arch x86_64 %t.o -o %t.out
|
||||
; RUN: %test_debuginfo %s %t.out
|
||||
; XFAIL: *
|
||||
; XTARGET: darwin
|
||||
|
||||
target triple = "x86_64-apple-darwin10.0.0"
|
||||
|
||||
define i32 @f1() nounwind ssp {
|
||||
; DEBUGGER: break f1
|
||||
; DEBUGGER: r
|
||||
; DEBUGGER: n
|
||||
; DEBUGGER: p i
|
||||
; CHECK: $1 = 42
|
||||
entry:
|
||||
%i = alloca i32, align 4
|
||||
call void @llvm.dbg.declare(metadata !{i32* %i}, metadata !10), !dbg !12
|
||||
store i32 42, i32* %i, align 4, !dbg !13
|
||||
%tmp = load i32* %i, align 4, !dbg !14
|
||||
ret i32 %tmp, !dbg !14
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
|
||||
|
||||
define i32 @f2() nounwind ssp {
|
||||
; DEBUGGER: break f2
|
||||
; DEBUGGER: c
|
||||
; DEBUGGER: n
|
||||
; DEBUGGER: p i
|
||||
; CHECK: $2 = 42
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{i32* %i}, metadata !15), !dbg !17
|
||||
%i = alloca i32, align 4
|
||||
store i32 42, i32* %i, align 4, !dbg !18
|
||||
%tmp = load i32* %i, align 4, !dbg !19
|
||||
ret i32 %tmp, !dbg !19
|
||||
}
|
||||
|
||||
; dbg.declare is dropped, as expected, by instruction selector.
|
||||
; THIS IS NOT EXPECTED TO WORK.
|
||||
define i32 @f3() nounwind ssp {
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{i32* %i}, metadata !20), !dbg !22
|
||||
br label %bbr
|
||||
bbr:
|
||||
%i = alloca i32, align 4
|
||||
store i32 42, i32* %i, align 4, !dbg !23
|
||||
%tmp = load i32* %i, align 4, !dbg !24
|
||||
ret i32 %tmp, !dbg !24
|
||||
}
|
||||
|
||||
; dbg.declare is dropped, as expected, by instruction selector.
|
||||
; THIS IS NOT EXPECTED TO WORK.
|
||||
define i32 @f4() nounwind ssp {
|
||||
entry:
|
||||
%i = alloca i32, align 4
|
||||
call void @llvm.dbg.declare(metadata !{i32* %i}, metadata !25), !dbg !27
|
||||
ret i32 42, !dbg !28
|
||||
}
|
||||
|
||||
define i32 @main() nounwind ssp {
|
||||
entry:
|
||||
%retval = alloca i32, align 4
|
||||
store i32 0, i32* %retval
|
||||
%call = call i32 @f1(), !dbg !29
|
||||
%call1 = call i32 @f2(), !dbg !31
|
||||
%call2 = call i32 @f3(), !dbg !32
|
||||
%call3 = call i32 @f4(), !dbg !33
|
||||
ret i32 0, !dbg !34
|
||||
}
|
||||
|
||||
!llvm.dbg.sp = !{!0, !6, !7, !8, !9}
|
||||
|
||||
!0 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f1", metadata !"f1", metadata !"f1", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @f1} ; [ DW_TAG_subprogram ]
|
||||
!1 = metadata !{i32 524329, metadata !"lv.c", metadata !"dbg_info_bugs", metadata !2} ; [ DW_TAG_file_type ]
|
||||
!2 = metadata !{i32 524305, i32 0, i32 12, metadata !"lv.c", metadata !"dbg_info_bugs", metadata !"clang version 2.9 (trunk 113428)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
|
||||
!3 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ]
|
||||
!4 = metadata !{metadata !5}
|
||||
!5 = metadata !{i32 524324, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
|
||||
!6 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f2", metadata !"f2", metadata !"f2", metadata !1, i32 8, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @f2} ; [ DW_TAG_subprogram ]
|
||||
!7 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f3", metadata !"f3", metadata !"f3", metadata !1, i32 14, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @f3} ; [ DW_TAG_subprogram ]
|
||||
!8 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f4", metadata !"f4", metadata !"f4", metadata !1, i32 20, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @f4} ; [ DW_TAG_subprogram ]
|
||||
!9 = metadata !{i32 524334, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata !1, i32 25, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ]
|
||||
!10 = metadata !{i32 524544, metadata !11, metadata !"i", metadata !1, i32 3, metadata !5} ; [ DW_TAG_auto_variable ]
|
||||
!11 = metadata !{i32 524299, metadata !0, i32 2, i32 10, metadata !1, i32 0} ; [ DW_TAG_lexical_block ]
|
||||
!12 = metadata !{i32 3, i32 7, metadata !11, null}
|
||||
!13 = metadata !{i32 4, i32 3, metadata !11, null}
|
||||
!14 = metadata !{i32 5, i32 3, metadata !11, null}
|
||||
!15 = metadata !{i32 524544, metadata !16, metadata !"i", metadata !1, i32 9, metadata !5} ; [ DW_TAG_auto_variable ]
|
||||
!16 = metadata !{i32 524299, metadata !6, i32 8, i32 10, metadata !1, i32 1} ; [ DW_TAG_lexical_block ]
|
||||
!17 = metadata !{i32 9, i32 7, metadata !16, null}
|
||||
!18 = metadata !{i32 10, i32 3, metadata !16, null}
|
||||
!19 = metadata !{i32 11, i32 3, metadata !16, null}
|
||||
!20 = metadata !{i32 524544, metadata !21, metadata !"i", metadata !1, i32 15, metadata !5} ; [ DW_TAG_auto_variable ]
|
||||
!21 = metadata !{i32 524299, metadata !7, i32 14, i32 10, metadata !1, i32 2} ; [ DW_TAG_lexical_block ]
|
||||
!22 = metadata !{i32 15, i32 7, metadata !21, null}
|
||||
!23 = metadata !{i32 16, i32 3, metadata !21, null}
|
||||
!24 = metadata !{i32 17, i32 3, metadata !21, null}
|
||||
!25 = metadata !{i32 524544, metadata !26, metadata !"i", metadata !1, i32 21, metadata !5} ; [ DW_TAG_auto_variable ]
|
||||
!26 = metadata !{i32 524299, metadata !8, i32 20, i32 10, metadata !1, i32 3} ; [ DW_TAG_lexical_block ]
|
||||
!27 = metadata !{i32 21, i32 7, metadata !26, null}
|
||||
!28 = metadata !{i32 22, i32 3, metadata !26, null}
|
||||
!29 = metadata !{i32 26, i32 3, metadata !30, null}
|
||||
!30 = metadata !{i32 524299, metadata !9, i32 25, i32 12, metadata !1, i32 4} ; [ DW_TAG_lexical_block ]
|
||||
!31 = metadata !{i32 27, i32 3, metadata !30, null}
|
||||
!32 = metadata !{i32 28, i32 3, metadata !30, null}
|
||||
!33 = metadata !{i32 29, i32 3, metadata !30, null}
|
||||
!34 = metadata !{i32 30, i32 3, metadata !30, null}
|
||||
@@ -1,109 +0,0 @@
|
||||
; This test case checks handling of llvm.dbg.declare intrinsic during isel.
|
||||
; RUN: %clang -arch x86_64 -O0 -mllvm -fast-isel=false -g %s -c -o %t.o
|
||||
; RUN: %clang -arch x86_64 %t.o -o %t.out
|
||||
; RUN: %test_debuginfo %s %t.out
|
||||
; XFAIL: *
|
||||
; XTARGET: darwin
|
||||
|
||||
target triple = "x86_64-apple-darwin10.0.0"
|
||||
|
||||
define i32 @f1() nounwind ssp {
|
||||
; DEBUGGER: break f1
|
||||
; DEBUGGER: r
|
||||
; DEBUGGER: n
|
||||
; DEBUGGER: p i
|
||||
; CHECK: $1 = 42
|
||||
entry:
|
||||
%i = alloca i32, align 4
|
||||
call void @llvm.dbg.declare(metadata !{i32* %i}, metadata !10), !dbg !12
|
||||
store i32 42, i32* %i, align 4, !dbg !13
|
||||
%tmp = load i32* %i, align 4, !dbg !14
|
||||
ret i32 %tmp, !dbg !14
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
|
||||
|
||||
define i32 @f2() nounwind ssp {
|
||||
; DEBUGGER: break f2
|
||||
; DEBUGGER: c
|
||||
; DEBUGGER: n
|
||||
; DEBUGGER: p i
|
||||
; CHECK: $2 = 42
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{i32* %i}, metadata !15), !dbg !17
|
||||
%i = alloca i32, align 4
|
||||
store i32 42, i32* %i, align 4, !dbg !18
|
||||
%tmp = load i32* %i, align 4, !dbg !19
|
||||
ret i32 %tmp, !dbg !19
|
||||
}
|
||||
|
||||
; dbg.declare is dropped, as expected, by instruction selector.
|
||||
; THIS IS NOT EXPECTED TO WORK.
|
||||
define i32 @f3() nounwind ssp {
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata !{i32* %i}, metadata !20), !dbg !22
|
||||
br label %bbr
|
||||
bbr:
|
||||
%i = alloca i32, align 4
|
||||
store i32 42, i32* %i, align 4, !dbg !23
|
||||
%tmp = load i32* %i, align 4, !dbg !24
|
||||
ret i32 %tmp, !dbg !24
|
||||
}
|
||||
|
||||
; dbg.declare is dropped, as expected, by instruction selector.
|
||||
; THIS IS NOT EXPECTED TO WORK.
|
||||
define i32 @f4() nounwind ssp {
|
||||
entry:
|
||||
%i = alloca i32, align 4
|
||||
call void @llvm.dbg.declare(metadata !{i32* %i}, metadata !25), !dbg !27
|
||||
ret i32 42, !dbg !28
|
||||
}
|
||||
|
||||
define i32 @main() nounwind ssp {
|
||||
entry:
|
||||
%retval = alloca i32, align 4
|
||||
store i32 0, i32* %retval
|
||||
%call = call i32 @f1(), !dbg !29
|
||||
%call1 = call i32 @f2(), !dbg !31
|
||||
%call2 = call i32 @f3(), !dbg !32
|
||||
%call3 = call i32 @f4(), !dbg !33
|
||||
ret i32 0, !dbg !34
|
||||
}
|
||||
|
||||
!llvm.dbg.sp = !{!0, !6, !7, !8, !9}
|
||||
|
||||
!0 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f1", metadata !"f1", metadata !"f1", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @f1} ; [ DW_TAG_subprogram ]
|
||||
!1 = metadata !{i32 524329, metadata !"lv.c", metadata !"dbg_info_bugs", metadata !2} ; [ DW_TAG_file_type ]
|
||||
!2 = metadata !{i32 524305, i32 0, i32 12, metadata !"lv.c", metadata !"dbg_info_bugs", metadata !"clang version 2.9 (trunk 113428)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
|
||||
!3 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ]
|
||||
!4 = metadata !{metadata !5}
|
||||
!5 = metadata !{i32 524324, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
|
||||
!6 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f2", metadata !"f2", metadata !"f2", metadata !1, i32 8, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @f2} ; [ DW_TAG_subprogram ]
|
||||
!7 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f3", metadata !"f3", metadata !"f3", metadata !1, i32 14, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @f3} ; [ DW_TAG_subprogram ]
|
||||
!8 = metadata !{i32 524334, i32 0, metadata !1, metadata !"f4", metadata !"f4", metadata !"f4", metadata !1, i32 20, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @f4} ; [ DW_TAG_subprogram ]
|
||||
!9 = metadata !{i32 524334, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata !1, i32 25, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ]
|
||||
!10 = metadata !{i32 524544, metadata !11, metadata !"i", metadata !1, i32 3, metadata !5} ; [ DW_TAG_auto_variable ]
|
||||
!11 = metadata !{i32 524299, metadata !0, i32 2, i32 10, metadata !1, i32 0} ; [ DW_TAG_lexical_block ]
|
||||
!12 = metadata !{i32 3, i32 7, metadata !11, null}
|
||||
!13 = metadata !{i32 4, i32 3, metadata !11, null}
|
||||
!14 = metadata !{i32 5, i32 3, metadata !11, null}
|
||||
!15 = metadata !{i32 524544, metadata !16, metadata !"i", metadata !1, i32 9, metadata !5} ; [ DW_TAG_auto_variable ]
|
||||
!16 = metadata !{i32 524299, metadata !6, i32 8, i32 10, metadata !1, i32 1} ; [ DW_TAG_lexical_block ]
|
||||
!17 = metadata !{i32 9, i32 7, metadata !16, null}
|
||||
!18 = metadata !{i32 10, i32 3, metadata !16, null}
|
||||
!19 = metadata !{i32 11, i32 3, metadata !16, null}
|
||||
!20 = metadata !{i32 524544, metadata !21, metadata !"i", metadata !1, i32 15, metadata !5} ; [ DW_TAG_auto_variable ]
|
||||
!21 = metadata !{i32 524299, metadata !7, i32 14, i32 10, metadata !1, i32 2} ; [ DW_TAG_lexical_block ]
|
||||
!22 = metadata !{i32 15, i32 7, metadata !21, null}
|
||||
!23 = metadata !{i32 16, i32 3, metadata !21, null}
|
||||
!24 = metadata !{i32 17, i32 3, metadata !21, null}
|
||||
!25 = metadata !{i32 524544, metadata !26, metadata !"i", metadata !1, i32 21, metadata !5} ; [ DW_TAG_auto_variable ]
|
||||
!26 = metadata !{i32 524299, metadata !8, i32 20, i32 10, metadata !1, i32 3} ; [ DW_TAG_lexical_block ]
|
||||
!27 = metadata !{i32 21, i32 7, metadata !26, null}
|
||||
!28 = metadata !{i32 22, i32 3, metadata !26, null}
|
||||
!29 = metadata !{i32 26, i32 3, metadata !30, null}
|
||||
!30 = metadata !{i32 524299, metadata !9, i32 25, i32 12, metadata !1, i32 4} ; [ DW_TAG_lexical_block ]
|
||||
!31 = metadata !{i32 27, i32 3, metadata !30, null}
|
||||
!32 = metadata !{i32 28, i32 3, metadata !30, null}
|
||||
!33 = metadata !{i32 29, i32 3, metadata !30, null}
|
||||
!34 = metadata !{i32 30, i32 3, metadata !30, null}
|
||||
@@ -1,21 +0,0 @@
|
||||
// RUN: %clangxx -O0 -g %s -c -o %t.o
|
||||
// RUN: %test_debuginfo %s %t.o
|
||||
// Radar 9440721
|
||||
// If debug info for my_number() is emitted outside function foo's scope
|
||||
// then a debugger may not be able to handle it. At least one version of
|
||||
// gdb crashes in such cases.
|
||||
|
||||
// DEBUGGER: ptype foo
|
||||
// CHECK: type = int (void)
|
||||
|
||||
int foo() {
|
||||
struct Local {
|
||||
static int my_number() {
|
||||
return 42;
|
||||
}
|
||||
};
|
||||
|
||||
int i = 0;
|
||||
i = Local::my_number();
|
||||
return i + 1;
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
// RUN: %clangxx -O0 -g %s -c -o %t.o
|
||||
// RUN: %clangxx %t.o -o %t.out
|
||||
// RUN: %test_debuginfo %s %t.out
|
||||
// Radar 8775834
|
||||
// DEBUGGER: break 61
|
||||
// DEBUGGER: r
|
||||
// DEBUGGER: p a
|
||||
// CHECK: $1 = (A &)
|
||||
// CHECK: _vptr$A =
|
||||
// CHECK: m_int = 12
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A (int i=0);
|
||||
A (const A& rhs);
|
||||
const A&
|
||||
operator= (const A& rhs);
|
||||
virtual ~A() {}
|
||||
|
||||
int get_int();
|
||||
|
||||
protected:
|
||||
int m_int;
|
||||
};
|
||||
|
||||
A::A (int i) :
|
||||
m_int(i)
|
||||
{
|
||||
}
|
||||
|
||||
A::A (const A& rhs) :
|
||||
m_int (rhs.m_int)
|
||||
{
|
||||
}
|
||||
|
||||
const A &
|
||||
A::operator =(const A& rhs)
|
||||
{
|
||||
m_int = rhs.m_int;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int A::get_int()
|
||||
{
|
||||
return m_int;
|
||||
}
|
||||
|
||||
class B
|
||||
{
|
||||
public:
|
||||
B () {}
|
||||
|
||||
A AInstance();
|
||||
};
|
||||
|
||||
A
|
||||
B::AInstance()
|
||||
{
|
||||
A a(12);
|
||||
return a;
|
||||
}
|
||||
|
||||
int main (int argc, char const *argv[])
|
||||
{
|
||||
B b;
|
||||
int return_val = b.AInstance().get_int();
|
||||
|
||||
A a(b.AInstance());
|
||||
return return_val;
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
; This test checks debug info of unused, zero extended argument.
|
||||
; RUN: %clang -arch x86_64 -mllvm -fast-isel=false %s -c -o %t.o
|
||||
; RUN: %clang -arch x86_64 %t.o -o %t.out
|
||||
; RUN: %test_debuginfo %s %t.out
|
||||
; XFAIL: *
|
||||
; XTARGET: darwin
|
||||
; Radar 9422775
|
||||
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||
target triple = "x86_64-apple-macosx10.6.7"
|
||||
|
||||
%class.aClass = type { float }
|
||||
|
||||
; DEBUGGER: break aClass::setValues
|
||||
; DEBUGGER: r
|
||||
; DEBUGGER: p Filter
|
||||
; CHECK: true
|
||||
|
||||
define void @_ZN6aClass9setValuesEibf(%class.aClass* nocapture %this, i32 %ch, i1 zeroext %Filter, float %a1) nounwind noinline ssp align 2 {
|
||||
entry:
|
||||
tail call void @llvm.dbg.value(metadata !{%class.aClass* %this}, i64 0, metadata !19), !dbg !25
|
||||
tail call void @llvm.dbg.value(metadata !{i32 %ch}, i64 0, metadata !20), !dbg !26
|
||||
tail call void @llvm.dbg.value(metadata !{i1 %Filter}, i64 0, metadata !21), !dbg !27
|
||||
tail call void @llvm.dbg.value(metadata !{float %a1}, i64 0, metadata !22), !dbg !28
|
||||
%m = getelementptr inbounds %class.aClass* %this, i64 0, i32 0, !dbg !29
|
||||
store float %a1, float* %m, align 4, !dbg !29, !tbaa !31
|
||||
ret void, !dbg !34
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
|
||||
|
||||
define i32 @main() nounwind ssp {
|
||||
entry:
|
||||
%a = alloca %class.aClass, align 4
|
||||
call void @llvm.dbg.declare(metadata !{%class.aClass* %a}, metadata !23), !dbg !35
|
||||
call void @_ZN6aClass9setValuesEibf(%class.aClass* %a, i32 undef, i1 zeroext 1, float 1.000000e+00), !dbg !36
|
||||
ret i32 0, !dbg !37
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.dbg.sp = !{!1, !12, !16}
|
||||
!llvm.dbg.lv._ZN6aClass9setValuesEibf = !{!19, !20, !21, !22}
|
||||
!llvm.dbg.lv.main = !{!23}
|
||||
|
||||
!0 = metadata !{i32 589841, i32 0, i32 4, metadata !"two.cpp", metadata !"/private/tmp/inc", metadata !"clang version 3.0 (trunk 131411)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
|
||||
!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"setValues", metadata !"setValues", metadata !"_ZN6aClass9setValuesEibf", metadata !3, i32 6, metadata !7, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 true, null, null} ; [ DW_TAG_subprogram ]
|
||||
!2 = metadata !{i32 589826, metadata !0, metadata !"aClass", metadata !3, i32 2, i64 32, i64 32, i32 0, i32 0, null, metadata !4, i32 0, null, null} ; [ DW_TAG_class_type ]
|
||||
!3 = metadata !{i32 589865, metadata !"./one.h", metadata !"/private/tmp/inc", metadata !0} ; [ DW_TAG_file_type ]
|
||||
!4 = metadata !{metadata !5, metadata !1}
|
||||
!5 = metadata !{i32 589837, metadata !3, metadata !"m", metadata !3, i32 4, i64 32, i64 32, i64 0, i32 1, metadata !6} ; [ DW_TAG_member ]
|
||||
!6 = metadata !{i32 589860, metadata !0, metadata !"float", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ]
|
||||
!7 = metadata !{i32 589845, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
|
||||
!8 = metadata !{null, metadata !9, metadata !10, metadata !11, metadata !6}
|
||||
!9 = metadata !{i32 589839, metadata !0, metadata !"", i32 0, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !2} ; [ DW_TAG_pointer_type ]
|
||||
!10 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
|
||||
!11 = metadata !{i32 589860, metadata !0, metadata !"bool", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 2} ; [ DW_TAG_base_type ]
|
||||
!12 = metadata !{i32 589870, i32 0, metadata !13, metadata !"setValues", metadata !"setValues", metadata !"_ZN6aClass9setValuesEibf", metadata !13, i32 4, metadata !14, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, void (%class.aClass*, i32, i1, float)* @_ZN6aClass9setValuesEibf, null, metadata !1} ; [ DW_TAG_subprogram ]
|
||||
!13 = metadata !{i32 589865, metadata !"two.cpp", metadata !"/private/tmp/inc", metadata !0} ; [ DW_TAG_file_type ]
|
||||
!14 = metadata !{i32 589845, metadata !13, metadata !"", metadata !13, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !15, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
|
||||
!15 = metadata !{null}
|
||||
!16 = metadata !{i32 589870, i32 0, metadata !13, metadata !"main", metadata !"main", metadata !"", metadata !13, i32 9, metadata !17, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 ()* @main, null, null} ; [ DW_TAG_subprogram ]
|
||||
!17 = metadata !{i32 589845, metadata !13, metadata !"", metadata !13, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !18, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
|
||||
!18 = metadata !{metadata !10}
|
||||
!19 = metadata !{i32 590081, metadata !12, metadata !"this", metadata !13, i32 16777219, metadata !9, i32 64} ; [ DW_TAG_arg_variable ]
|
||||
!20 = metadata !{i32 590081, metadata !12, metadata !"ch", metadata !13, i32 33554435, metadata !10, i32 0} ; [ DW_TAG_arg_variable ]
|
||||
!21 = metadata !{i32 590081, metadata !12, metadata !"Filter", metadata !13, i32 50331651, metadata !11, i32 0} ; [ DW_TAG_arg_variable ]
|
||||
!22 = metadata !{i32 590081, metadata !12, metadata !"a1", metadata !13, i32 67108867, metadata !6, i32 0} ; [ DW_TAG_arg_variable ]
|
||||
!23 = metadata !{i32 590080, metadata !24, metadata !"a", metadata !13, i32 10, metadata !2, i32 0} ; [ DW_TAG_auto_variable ]
|
||||
!24 = metadata !{i32 589835, metadata !16, i32 9, i32 1, metadata !13, i32 1} ; [ DW_TAG_lexical_block ]
|
||||
!25 = metadata !{i32 3, i32 40, metadata !12, null}
|
||||
!26 = metadata !{i32 3, i32 54, metadata !12, null}
|
||||
!27 = metadata !{i32 3, i32 63, metadata !12, null}
|
||||
!28 = metadata !{i32 3, i32 77, metadata !12, null}
|
||||
!29 = metadata !{i32 5, i32 2, metadata !30, null}
|
||||
!30 = metadata !{i32 589835, metadata !12, i32 4, i32 1, metadata !13, i32 0} ; [ DW_TAG_lexical_block ]
|
||||
!31 = metadata !{metadata !"float", metadata !32}
|
||||
!32 = metadata !{metadata !"omnipotent char", metadata !33}
|
||||
!33 = metadata !{metadata !"Simple C/C++ TBAA", null}
|
||||
!34 = metadata !{i32 6, i32 1, metadata !30, null}
|
||||
!35 = metadata !{i32 10, i32 11, metadata !24, null}
|
||||
!36 = metadata !{i32 11, i32 4, metadata !24, null}
|
||||
!37 = metadata !{i32 12, i32 4, metadata !24, null}
|
||||
@@ -1,9 +0,0 @@
|
||||
LLDB Installation Instructions
|
||||
==============================
|
||||
|
||||
Note that LLDB currently only builds out of the box on Mac OS X with Xcode, but
|
||||
patches to improve portability are definitely welcome.
|
||||
|
||||
In addition to using Xcode you'll need to enable code signing on your system
|
||||
to either build lldb or debug using lldb. Please see the code signing
|
||||
documentation in docs/code-signing.txt for more detailed directions.
|
||||
@@ -1,38 +0,0 @@
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2010 Apple Inc.
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
||||
LLDB Team
|
||||
|
||||
http://lldb.llvm.org/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal with
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimers.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimers in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of the LLDB Team, copyright holders, nor the names of
|
||||
its contributors may be used to endorse or promote products derived from
|
||||
this Software without specific prior written permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
##===- Makefile --------------------------------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
# If LLDB_LEVEL is not set, then we are the top-level Makefile. Otherwise, we
|
||||
# are being included from a subdirectory makefile.
|
||||
|
||||
ifndef LLDB_LEVEL
|
||||
|
||||
IS_TOP_LEVEL := 1
|
||||
LLDB_LEVEL := .
|
||||
DIRS := include source lib tools
|
||||
|
||||
PARALLEL_DIRS :=
|
||||
endif
|
||||
|
||||
###
|
||||
# Common Makefile code, shared by all LLDB Makefiles.
|
||||
|
||||
# Set LLVM source root level.
|
||||
LEVEL := $(LLDB_LEVEL)/../..
|
||||
|
||||
# Include LLVM common makefile.
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
||||
# Set Python include directory
|
||||
PYTHON_INC_DIR = $(shell python-config --includes)
|
||||
# Set common LLDB build flags.
|
||||
CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/include
|
||||
CPP.Flags += -I$(PROJ_OBJ_DIR)/$(LLDB_LEVEL)/include
|
||||
CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/../clang/include
|
||||
CPP.Flags += -I$(PROJ_OBJ_DIR)/$(LLDB_LEVEL)/../clang/include
|
||||
CPP.Flags += $(PYTHON_INC_DIR)
|
||||
CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source
|
||||
CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Utility
|
||||
CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/Utility
|
||||
ifeq ($(HOST_OS),Darwin)
|
||||
CPP.Flags += -F/System/Library/Frameworks -F/System/Library/PrivateFrameworks
|
||||
endif
|
||||
ifdef LLDB_VENDOR
|
||||
CPP.Flags += -DLLDB_VENDOR='"$(LLDB_VENDOR) "'
|
||||
endif
|
||||
|
||||
# Disable -fstrict-aliasing. Darwin disables it by default (and LLVM doesn't
|
||||
# work with it enabled with GCC), Clang/llvm-gc don't support it yet, and newer
|
||||
# GCC's have false positive warnings with it on Linux (which prove a pain to
|
||||
# fix). For example:
|
||||
# http://gcc.gnu.org/PR41874
|
||||
# http://gcc.gnu.org/PR41838
|
||||
#
|
||||
# We can revisit this when LLVM/Clang support it.
|
||||
CXX.Flags += -fno-strict-aliasing
|
||||
|
||||
# Do not warn about pragmas. In particular, we are looking to ignore the
|
||||
# "#pragma mark" construct which GCC warns about on platforms other than Darwin.
|
||||
EXTRA_OPTIONS += -Wno-unknown-pragmas
|
||||
|
||||
###
|
||||
# LLDB Top Level specific stuff.
|
||||
|
||||
ifeq ($(IS_TOP_LEVEL),1)
|
||||
|
||||
ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
|
||||
$(RecursiveTargets)::
|
||||
$(Verb) if [ ! -f test/Makefile ]; then \
|
||||
$(MKDIR) test; \
|
||||
$(CP) $(PROJ_SRC_DIR)/test/Makefile test/Makefile; \
|
||||
fi
|
||||
endif
|
||||
|
||||
test::
|
||||
@ $(MAKE) -C test
|
||||
|
||||
#report::
|
||||
# @ $(MAKE) -C test report
|
||||
|
||||
#clean::
|
||||
# @ $(MAKE) -C test clean
|
||||
|
||||
tags::
|
||||
$(Verb) etags `find . -type f -name '*.h' -or -name '*.cpp' | \
|
||||
grep -v /lib/Headers | grep -v /test/`
|
||||
|
||||
cscope.files:
|
||||
find tools lib include -name '*.cpp' \
|
||||
-or -name '*.def' \
|
||||
-or -name '*.td' \
|
||||
-or -name '*.h' > cscope.files
|
||||
|
||||
.PHONY: test report clean cscope.files
|
||||
|
||||
endif
|
||||
@@ -1,50 +0,0 @@
|
||||
This document describes how to build a debug version of LLVM for use with
|
||||
LLDB, and how to make LLDB use it.
|
||||
|
||||
It assumes that you are using the Xcode 3 series (I used 3.2.4) to build
|
||||
LLDB. It also assumes that your shell is /bin/bash, and that you are
|
||||
currently at a shell prompt in a checked-out LLDB repository.
|
||||
|
||||
1. Check out LLVM and Clang from their repositories. To determine
|
||||
the revision to use, consult scripts/build-llvm.pl (this is done
|
||||
in the first command line below). !!! WARNING Do not use the
|
||||
name "llvm" for your checkout, for reasons described in part 3
|
||||
below.
|
||||
|
||||
$ export CLANG_REVISION=`cat scripts/build-llvm.pl | grep ^our.*llvm_revision | cut -d \' -f 2,2`
|
||||
$ svn co -r $CLANG_REVISION http://llvm.org/svn/llvm-project/llvm/trunk llvm.checkout
|
||||
$ svn co -r $CLANG_REVISION http://llvm.org/svn/llvm-project/cfe/trunk llvm.checkout/tools/clang
|
||||
|
||||
2. Configure LLVM/Clang with the proper options and compilers. I use:
|
||||
|
||||
$ cd llvm.checkout
|
||||
$ CC="cc -g -O0" CXX="c++ -g -O0" ./configure --disable-optimized --enable-assertions --enable-targets=x86_64,arm
|
||||
$ CC="cc -g -O0" CXX="c++ -g -O0" make -j 2
|
||||
$ cd ..
|
||||
|
||||
3. Create a link to the built LLVM. !!! WARNING: Do not rename the
|
||||
directory! The LLVM builder script that runs as part of the Xcode
|
||||
build keys off the fact that llvm/ is a symlink to recognize that
|
||||
we are building with a custom debug build.
|
||||
|
||||
$ ln -sf llvm.checkout llvm
|
||||
|
||||
4. Make sure that your Xcode project is set up correctly. Open
|
||||
lldb.xcodeproj and do the following:
|
||||
|
||||
Under "Targets" in the Groups & Files navigator, double-click
|
||||
lldb-tool. In the resulting window, select "Debug" from the
|
||||
"Configuration:" drop-down. Then, make sure that the setting
|
||||
"Build Active Architecture Only" is enabled. Close the window.
|
||||
|
||||
Under "Targets" in the Groups & Files navigator, double-click
|
||||
LLDB. In the resulting window, select "Debug" from the
|
||||
"Configuration:" drop-down. Then, make sure that the setting
|
||||
"Build Active Architecture Only" is enabled. Close the window.
|
||||
|
||||
5. Ensure that Xcode is building the lldb-tool target in Debug
|
||||
configuration for your architecture (typically x86_64). You
|
||||
can usually pick these options from the Overview drop-down at
|
||||
the top left of the Xcode window.
|
||||
|
||||
6. Build lldb.xcodeproj.
|
||||
@@ -1,53 +0,0 @@
|
||||
On MacOSX lldb needs to be code signed. The Debug and Release builds
|
||||
are set to code sign using a code signing certificate named
|
||||
lldb_codesign.
|
||||
|
||||
If you don't have one yet you will need to:
|
||||
- Launch /Applications/Utilities/Keychain Access.app
|
||||
|
||||
- In Keychain Access select the "login" keychain in the "Keychains"
|
||||
list in the upper left hand corner of the window.
|
||||
|
||||
- Select the following menu item:
|
||||
|
||||
Keychain Access->Certificate Assistant->Create a Certificate...
|
||||
|
||||
- Set the following settings
|
||||
|
||||
Name = lldb_codesign
|
||||
Identity Type = Self Signed Root
|
||||
Certificate Type = Code Signing
|
||||
|
||||
- Click Create
|
||||
- Click Continue
|
||||
- Click Done
|
||||
- Click on the "My Certificates"
|
||||
- Double click on your new lldb_codesign certificate
|
||||
- Turn down the "Trust" disclosure triangle
|
||||
|
||||
Change:
|
||||
When using this certificate: Always Trust
|
||||
|
||||
- Enter your login password to confirm and make it trusted
|
||||
|
||||
The next steps are necessary on SnowLeopard, but are probably because of a bug
|
||||
how Keychain Access makes certificates.
|
||||
[Note: These also apply for Lion.]
|
||||
|
||||
- Option-drag the new lldb_codesign certificate from the login keychain to
|
||||
the System keychain in the Keychains pane of the main Keychain Access window
|
||||
to make a copy of this certificate in the System keychain. You'll have to
|
||||
authorize a few more times, set it to be "Always trusted" when asked.
|
||||
- Switch to the System keychain, and drag the copy of lldb_codesign you just
|
||||
made there onto the desktop.
|
||||
- Switch to Terminal, and run the following:
|
||||
|
||||
sudo security add-trust -d -r trustRoot -p basic -p codeSign -k /Library/Keychains/System.keychain ~/Desktop/lldb_codesign.cer
|
||||
|
||||
- Right click on the "lldb_codesign" certificate in the "System" keychain (NOT
|
||||
"login", but the one in "System"), and select "Delete" to delete it from
|
||||
the "System" keychain.
|
||||
- Reboot
|
||||
- Clean and rebuild lldb and you should be able to debug.
|
||||
|
||||
That should do it.
|
||||
@@ -1,488 +0,0 @@
|
||||
Here's a short precis of how to run lldb if you are familiar with the
|
||||
gdb command set:
|
||||
|
||||
|
||||
1) LLDB Command Structure:
|
||||
|
||||
First some details on lldb command structure to help orient you...
|
||||
|
||||
Unlike gdb's command set, which is rather free-form, we tried to make
|
||||
the lldb command syntax fairly structured. The commands are all of the
|
||||
form
|
||||
|
||||
<noun> <verb> [-options [option-value]] [argument [argument...]]
|
||||
|
||||
The command line parsing is done before command execution, so it is
|
||||
uniform across all the commands. The command syntax is very simple,
|
||||
basically arguments, options and option values are all white-space
|
||||
separated. If you need to put a backslash or double-quote character
|
||||
in an argument you back-slash it in the argument. That makes the
|
||||
command syntax more regular, but it also means you may have to
|
||||
quote some arguments in lldb that you wouldn't in gdb.
|
||||
|
||||
Options can be placed anywhere on the command line, but if the arguments
|
||||
begin with a "-" then you have to tell lldb that you're done with options
|
||||
using the "--" option. So for instance, the "process launch" command takes
|
||||
the "-s" option to mean "stop the process at the first instruction". It's
|
||||
arguments are the arguments you are passing to the program. So if you wanted
|
||||
to pass an argument that contained a "-" you would have to do:
|
||||
|
||||
(lldb) process launch -- -program_arg value
|
||||
|
||||
We also tried to reduce the number of special purpose argument
|
||||
parsers, which sometimes forces the user to be a little more explicit
|
||||
about stating their intentions. The first instance you'll note of
|
||||
this is the breakpoint command. In gdb, to set a breakpoint, you
|
||||
would just say:
|
||||
|
||||
(gdb) break foo.c:12
|
||||
|
||||
or
|
||||
|
||||
(gdb) break foo
|
||||
|
||||
if foo is a function. As time went on, the parser that tells foo.c:12
|
||||
from foo from foo.c::foo (which means the function foo in the file
|
||||
foo.c) got more and more complex and bizarre, and especially in C++
|
||||
there are times where there's really no way to specify the function
|
||||
you want to break on. The lldb commands are more verbose but also precise.
|
||||
So you say:
|
||||
|
||||
(lldb) breakpoint set -f foo.c -l 12
|
||||
|
||||
to set a file & line breakpoint. To set a breakpoint on a function
|
||||
by name, you do:
|
||||
|
||||
(lldb) breakpoint set -n foo
|
||||
|
||||
This can allow us to be more expressive, so you can say:
|
||||
|
||||
(lldb) breakpoint set -M foo
|
||||
|
||||
to break on all C++ methods named foo, or:
|
||||
|
||||
(lldb) breakpoint set -S alignLeftEdges:
|
||||
|
||||
to set a breakpoint on all ObjC selectors called alignLeftEdges:. It
|
||||
also makes it easy to compose specifications, like:
|
||||
|
||||
(lldb) breakpoint set -s foo.dylib -n foo
|
||||
|
||||
for all functions called foo in the shared library foo.dylib. Suggestions
|
||||
on more interesting primitives of this sort are also very welcome.
|
||||
|
||||
So for instance:
|
||||
|
||||
(lldb) breakpoint set -n "-[SKTGraphicView alignLeftEdges:]"
|
||||
|
||||
Just like gdb, the lldb command interpreter does a shortest unique
|
||||
string match on command names, so the previous command can also be
|
||||
typed:
|
||||
|
||||
(lldb) b s -n "-[SKTGraphicView alignLeftEdges:]"
|
||||
|
||||
lldb also supports command completion for source file names, symbol
|
||||
names, file names, etc. Completion is initiated by a hitting a <TAB>.
|
||||
Individual options in a command can have different completers, so for
|
||||
instance the -f option in "breakpoint" completes to source files, the
|
||||
-s option to currently loaded shared libraries, etc... We can even do
|
||||
things like if you specify -s, and are completing on -f, we will only
|
||||
list source files in the shared library specified by -s...
|
||||
|
||||
The individual commands are pretty extensively documented, using
|
||||
the "help" command. And there is an "apropos" command that will
|
||||
search the help for a particular word and dump a summary help string
|
||||
for each matching command.
|
||||
|
||||
Finally, there is a mechanism to construct aliases for commonly used
|
||||
commands. So for instance if you get annoyed typing
|
||||
|
||||
(lldb) b s -f foo.c -l 12
|
||||
|
||||
you can do:
|
||||
|
||||
(lldb) command alias bfl breakpoint set -f %1 -l %2
|
||||
(lldb) bfl foo.c 12
|
||||
|
||||
We have added a few aliases for commonly used commands (e.g. "step",
|
||||
"next" and "continue") but we haven't tried to be exhaustive because
|
||||
in our experience it is more convenient to make the basic commands
|
||||
unique down to a letter or two, and then learn these sequences than
|
||||
fill the namespace with lots of aliases, and then have to type them
|
||||
all the way out.
|
||||
|
||||
However, users are free to customize lldb's command set however they
|
||||
like, and since lldb reads the file ~/.lldbinit at startup, you can
|
||||
store all your aliases there and they will be generally available to
|
||||
you. Your aliases are also documented in the help command so you can
|
||||
remind yourself of what you've set up.
|
||||
|
||||
lldb also has a built-in Python interpreter, which is accessible by
|
||||
the "script" command. All the functionality of the debugger is
|
||||
available as classes in the Python interpreter, so the more complex
|
||||
commands that in gdb you would introduce with the "define" command can
|
||||
be done by writing Python functions using the lldb-Python library,
|
||||
then loading the scripts into your running session and accessing them
|
||||
with the "script" command.
|
||||
|
||||
|
||||
|
||||
2) A typical session:
|
||||
|
||||
|
||||
a) Setting the program to debug:
|
||||
|
||||
|
||||
As with gdb, you can start lldb and specify the file you wish to debug
|
||||
on the command line:
|
||||
|
||||
$ lldb /Projects/Sketch/build/Debug/Sketch.app
|
||||
Current executable set to '/Projects/Sketch/build/Debug/Sketch.app' (x86_64).
|
||||
|
||||
or you can specify it after the fact with the "file" command:
|
||||
|
||||
(lldb) file /Projects/Sketch/build/Debug/Sketch.app
|
||||
Current executable set to '/Projects/Sketch/build/Debug/Sketch.app' (x86_64).
|
||||
|
||||
|
||||
b) Setting breakpoints:
|
||||
|
||||
|
||||
We've discussed how to set breakpoints above. You can use "help break set"
|
||||
to see all the options for breakpoint setting. For instance, we might do:
|
||||
|
||||
(lldb) b s -S alignLeftEdges:
|
||||
Breakpoint created: 1: name = 'alignLeftEdges:', locations = 1, resolved = 1
|
||||
|
||||
You can find out about the breakpoints you've set with:
|
||||
|
||||
(lldb) break list
|
||||
Current breakpoints:
|
||||
1: name = 'alignLeftEdges:', locations = 1, resolved = 1
|
||||
1.1: where = Sketch`-[SKTGraphicView alignLeftEdges:] + 33 at /Projects/Sketch/SKTGraphicView.m:1405, address = 0x0000000100010d5b, resolved, hit count = 0
|
||||
|
||||
Note that each "logical" breakpoint can have multiple "locations".
|
||||
The logical breakpoint has an integer id, and it's locations have an
|
||||
id within their parent breakpoint (the two are joined by a ".",
|
||||
e.g. 1.1 in the example above.)
|
||||
|
||||
Also the breakpoints remain "live" so that if another shared library
|
||||
were to be loaded that had another implementation of the
|
||||
"alignLeftEdges:" selector, the new location would be added to
|
||||
breakpoint 1 (e.g. a "1.2" breakpoint would be set on the newly loaded
|
||||
selector).
|
||||
|
||||
The other piece of information in the breakpoint listing is whether the
|
||||
breakpoint location was "resolved" or not. A location gets resolved when
|
||||
the file address it corresponds to gets loaded into the program you are
|
||||
debugging. For instance if you set a breakpoint in a shared library that
|
||||
then gets unloaded, that breakpoint location will remain, but it will no
|
||||
longer be "resolved".
|
||||
|
||||
One other thing to note for gdb users is that lldb acts like gdb with:
|
||||
|
||||
(gdb) set breakpoint pending on
|
||||
|
||||
That is, lldb should always make a breakpoint from your specification, even
|
||||
if it couldn't find any locations that match the specification. You can tell
|
||||
whether the expression was resolved or not by checking the locations field
|
||||
in "breakpoint list", and we report the breakpoint as "pending" when you
|
||||
set it so you can tell you've made a typo more easily, if that was indeed
|
||||
the reason no locations were found:
|
||||
|
||||
(lldb) b s -f no_such_file.c -l 10000000
|
||||
Breakpoint created: 1: file ='no_such_file.c', line = 10000000, locations = 0 (pending)
|
||||
|
||||
You can delete, disable, set conditions and ignore counts either on all the
|
||||
locations generated by your logical breakpoint, or on particular locations
|
||||
your specification resolved to. For instance if we wanted to add a command
|
||||
to print a backtrace when we hit this breakpoint we could do:
|
||||
|
||||
(lldb) b command add -c 1.1
|
||||
Enter your debugger command(s). Type 'DONE' to end.
|
||||
> bt
|
||||
> DONE
|
||||
|
||||
The "-c" option specifies that the breakpoint command is a set of lldb
|
||||
commmand interpreter commands. Use "-s" if you want to implement your
|
||||
breakpoint command using the Python interface instead.
|
||||
|
||||
|
||||
c) Running the program:
|
||||
|
||||
Then you can either launch the process with the command:
|
||||
|
||||
(lldb) process launch
|
||||
|
||||
or its alias:
|
||||
|
||||
(lldb) r
|
||||
|
||||
Or you can attach to a process by name with:
|
||||
|
||||
(lldb) process attach -n Sketch
|
||||
|
||||
the "attach by name" also supports the "-w" option which waits for the
|
||||
next process of that name to show up, and attaches to that. You can also
|
||||
attach by PID:
|
||||
|
||||
(lldb) process attach -p 12345
|
||||
Process 46915 Attaching
|
||||
(lldb) Process 46915 Stopped
|
||||
1 of 3 threads stopped with reasons:
|
||||
* thread #1: tid = 0x2c03, 0x00007fff85cac76a, where = libSystem.B.dylib`__getdirentries64 + 10, stop reason = signal = SIGSTOP, queue = com.apple.main-thread
|
||||
|
||||
Note that we tell you that "1 of 3 threads stopped with reasons" and
|
||||
then list those threads. In a multi-threaded environment it is very
|
||||
common for more than one thread to hit your breakpoint(s) before the
|
||||
kernel actually returns control to the debugger. In that case, you
|
||||
will see all the threads that stopped for some interesting reason
|
||||
listed in the stop message.
|
||||
|
||||
|
||||
d) Controlling execution:
|
||||
|
||||
|
||||
After launching, we can continue until we hit our breakpoint. The primitive
|
||||
commands for process control all exist under the "thread" command:
|
||||
|
||||
(lldb) thread continue
|
||||
Resuming thread 0x2c03 in process 46915
|
||||
Resuming process 46915
|
||||
(lldb)
|
||||
|
||||
At present you can only operate on one thread at a time, but the
|
||||
design will ultimately support saying "step over the function in
|
||||
Thread 1, and step into the function in Thread 2, and continue Thread
|
||||
3" etc. When we eventually support keeping some threads running while
|
||||
others are stopped this will be particularly important. For
|
||||
convenience, however, all the stepping commands have easy aliases.
|
||||
So "thread continue" is just "c", etc.
|
||||
|
||||
The other program stepping commands are pretty much the same as in gdb.
|
||||
You've got:
|
||||
|
||||
1. (lldb) thread step-in
|
||||
The same as gdb's "step" -- there is also the alias "s" in lldb
|
||||
|
||||
2. (lldb) thread step-over
|
||||
The same as gdb's "next" -- there is also the alias "n" in lldb
|
||||
|
||||
3. (lldb) thread step-out
|
||||
The same as gdb's "finish" -- there is also the alias "f" in lldb
|
||||
|
||||
And the "by instruction" versions:
|
||||
|
||||
(lldb) thread step-inst
|
||||
(lldb) thread step-over-inst
|
||||
|
||||
Finally, there's:
|
||||
|
||||
(lldb) thread until 100
|
||||
|
||||
which runs the thread in the current frame till it reaches line 100 in
|
||||
this frame or stops if it leaves the current frame. This is a pretty
|
||||
close equivalent to gdb's "until" command.
|
||||
|
||||
|
||||
One thing here that might be a little disconcerting to gdb users here is that
|
||||
when you resume process execution, you immediately get a prompt back. That's
|
||||
because the lldb interpreter remains live when you are running the target.
|
||||
This allows you to set a breakpoint, etc without having to explicitly interrupt
|
||||
the program you are debugging. We're still working out all the operations
|
||||
that it is safe to do while running. But this way of operation will set us
|
||||
up for "no stop" debugging when we get to implementing that.
|
||||
|
||||
If you want to interrupt a running program do:
|
||||
|
||||
(lldb) process interrupt
|
||||
|
||||
To find out the state of the program, use:
|
||||
|
||||
(lldb) process status
|
||||
Process 47958 is running.
|
||||
|
||||
This is very convenient, but it does have the down-side that debugging
|
||||
programs that use stdin is no longer as straightforward. For now, you
|
||||
have to specify another tty to use as the program stdout & stdin using
|
||||
the appropriate options to "process launch", or start your program in
|
||||
another terminal and catch it with "process attach -w". We will come
|
||||
up with some more convenient way to juggle the terminal back & forth
|
||||
over time.
|
||||
|
||||
|
||||
e) Examining program state:
|
||||
|
||||
Once you've stopped, lldb will choose a current thread, usually the
|
||||
one that stopped "for a reason", and a current frame in that thread.
|
||||
Many the commands for inspecting state work on this current
|
||||
thread/frame.
|
||||
|
||||
To inspect the current state of your process, you can start with the
|
||||
threads:
|
||||
|
||||
(lldb) thread list
|
||||
Process 46915 state is Stopped
|
||||
* thread #1: tid = 0x2c03, 0x00007fff85cac76a, where = libSystem.B.dylib`__getdirentries64 + 10, stop reason = signal = SIGSTOP, queue = com.apple.main-thread
|
||||
thread #2: tid = 0x2e03, 0x00007fff85cbb08a, where = libSystem.B.dylib`kevent + 10, queue = com.apple.libdispatch-manager
|
||||
thread #3: tid = 0x2f03, 0x00007fff85cbbeaa, where = libSystem.B.dylib`__workq_kernreturn + 10
|
||||
|
||||
The * indicates that Thread 1 is the current thread. To get a
|
||||
backtrace for that thread, do:
|
||||
|
||||
(lldb) thread backtrace
|
||||
thread #1: tid = 0x2c03, stop reason = breakpoint 1.1, queue = com.apple.main-thread
|
||||
frame #0: 0x0000000100010d5b, where = Sketch`-[SKTGraphicView alignLeftEdges:] + 33 at /Projects/Sketch/SKTGraphicView.m:1405
|
||||
frame #1: 0x00007fff8602d152, where = AppKit`-[NSApplication sendAction:to:from:] + 95
|
||||
frame #2: 0x00007fff860516be, where = AppKit`-[NSMenuItem _corePerformAction] + 365
|
||||
frame #3: 0x00007fff86051428, where = AppKit`-[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] + 121
|
||||
frame #4: 0x00007fff860370c1, where = AppKit`-[NSMenu performKeyEquivalent:] + 272
|
||||
frame #5: 0x00007fff86035e69, where = AppKit`-[NSApplication _handleKeyEquivalent:] + 559
|
||||
frame #6: 0x00007fff85f06aa1, where = AppKit`-[NSApplication sendEvent:] + 3630
|
||||
frame #7: 0x00007fff85e9d922, where = AppKit`-[NSApplication run] + 474
|
||||
frame #8: 0x00007fff85e965f8, where = AppKit`NSApplicationMain + 364
|
||||
frame #9: 0x0000000100015ae3, where = Sketch`main + 33 at /Projects/Sketch/SKTMain.m:11
|
||||
frame #10: 0x0000000100000f20, where = Sketch`start + 52
|
||||
|
||||
You can also provide a list of threads to backtrace, or the keyword
|
||||
"all" to see all threads:
|
||||
|
||||
(lldb) thread backtrace all
|
||||
|
||||
Next task is inspecting data:
|
||||
|
||||
The most convenient way to inspect a frame's arguments and local variables is:
|
||||
|
||||
(lldb) frame variable
|
||||
self = (SKTGraphicView *) 0x0000000100208b40
|
||||
_cmd = (struct objc_selector *) 0x000000010001bae1
|
||||
sender = (id) 0x00000001001264e0
|
||||
selection = (NSArray *) 0x00000001001264e0
|
||||
i = (NSUInteger) 0x00000001001264e0
|
||||
c = (NSUInteger) 0x00000001001253b0
|
||||
|
||||
You can also choose particular variables to view:
|
||||
|
||||
(lldb) frame variable self
|
||||
(SKTGraphicView *) self = 0x0000000100208b40
|
||||
|
||||
The frame variable command is not a full expression parser but it
|
||||
does support some common operations like dereferencing:
|
||||
|
||||
(lldb) fr v *self
|
||||
(SKTGraphicView *) self = 0x0000000100208b40
|
||||
(NSView) NSView = {
|
||||
(NSResponder) NSResponder = {
|
||||
...
|
||||
|
||||
and structure element references:
|
||||
|
||||
(lldb) frame variable self.isa
|
||||
(struct objc_class *) self.isa = 0x0000000100023730
|
||||
|
||||
The frame variable command will also perform "object printing" operations on
|
||||
variables (currently we only support NSPrintForDebugger) with:
|
||||
|
||||
(lldb) fr v -o self
|
||||
(SKTGraphicView *) self = 0x0000000100208b40
|
||||
<SKTGraphicView: 0x100208b40>
|
||||
|
||||
You can select another frame to view with:
|
||||
|
||||
(lldb) frame select 9
|
||||
frame #9: 0x0000000100015ae3, where = Sketch`main + 33 at /Projects/Sketch/SKTMain.m:11
|
||||
8
|
||||
9
|
||||
10 int main(int argc, const char *argv[]) {
|
||||
11 -> return NSApplicationMain(argc, argv);
|
||||
12 }
|
||||
13
|
||||
14
|
||||
|
||||
Another neat trick that the variable list does is array references, so:
|
||||
|
||||
(lldb) fr v argv[0]
|
||||
(char const *) argv[0] = 0x00007fff5fbffaf8 "/Projects/Sketch/build/Debug/Sketch.app/Contents/MacOS/Sketch"
|
||||
|
||||
If you need to view more complex data or change program data, you can
|
||||
use the general "expression" command. It takes an expression and
|
||||
evaluates it in the scope of the currently selected frame. For instance:
|
||||
|
||||
(lldb) expr self
|
||||
$0 = (SKTGraphicView *) 0x0000000100135430
|
||||
(lldb) expr self = 0x00
|
||||
$1 = (SKTGraphicView *) 0x0000000000000000
|
||||
(lldb) frame var self
|
||||
(SKTGraphicView *) self = 0x0000000000000000
|
||||
|
||||
You can also call functions:
|
||||
|
||||
(lldb) expr (int) printf ("I have a pointer 0x%llx.\n", self)
|
||||
$2 = (int) 22
|
||||
I have a pointer 0x0.
|
||||
|
||||
One thing to note from this example is that lldb commands can be defined to
|
||||
take "raw" input. "expression" is one of these. So in the expression command,
|
||||
you don't have to quote your whole expression, nor backslash protect quotes,
|
||||
etc...
|
||||
|
||||
Finally, the results of the expressions are stored in persistent variables
|
||||
(of the form $[0-9]+) that you can use in further expressions, like:
|
||||
|
||||
(lldb) expr self = $0
|
||||
$4 = (SKTGraphicView *) 0x0000000100135430
|
||||
|
||||
f) Customization:
|
||||
|
||||
You can use the embedded Python interprter to add the following 'pwd' and 'cd' commands
|
||||
for your lldb session:
|
||||
|
||||
(lldb) script import os
|
||||
(lldb) command alias pwd script print os.getcwd()
|
||||
(lldb) command regex cd "s/^(.*)$/script os.chdir(os.path.expanduser('%1'))/"
|
||||
|
||||
...
|
||||
|
||||
(lldb) cd /tmp
|
||||
script os.chdir(os.path.expanduser('/tmp'))
|
||||
(lldb) pwd
|
||||
/private/tmp
|
||||
(lldb)
|
||||
|
||||
Or for a more capable 'cd' command, create ~/utils.py like this:
|
||||
|
||||
import os
|
||||
|
||||
def chdir(debugger, args, result, dict):
|
||||
"""Change the working directory, or cd to ${HOME}."""
|
||||
dir = args.strip()
|
||||
if dir:
|
||||
os.chdir(args)
|
||||
else:
|
||||
os.chdir(os.path.expanduser('~'))
|
||||
print "Current working directory: %s" % os.getcwd()
|
||||
|
||||
and, have the following in your ~/.lldbinit file:
|
||||
|
||||
script import os, sys
|
||||
script sys.path.append(os.path.expanduser('~'))
|
||||
script import utils
|
||||
command alias pwd script print os.getcwd()
|
||||
command script add -f utils.chdir cd
|
||||
|
||||
and, then in your lldb session, you can have:
|
||||
|
||||
(lldb) help cd
|
||||
|
||||
Change the working directory, or cd to ${HOME}.
|
||||
Syntax: cd
|
||||
(lldb) cd
|
||||
Current working directory: /Volumes/data/Users/johnny
|
||||
(lldb) cd /tmp
|
||||
Current working directory: /private/tmp
|
||||
(lldb) pwd
|
||||
/private/tmp
|
||||
(lldb)
|
||||
|
||||
For more examples of customization, look under the ToT/examples/customization
|
||||
directory.
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
os command: [['/bin/sh', '-c', 'make clean; make']]
|
||||
stdout: rm -rf "a.out" "a.out.dSYM" main.o main.d
|
||||
g++ -arch x86_64 -gdwarf-2 -O0 -c -o main.o main.cpp
|
||||
g++ -arch x86_64 -gdwarf-2 -O0 main.o -o "a.out"
|
||||
/usr/bin/dsymutil -o "a.out.dSYM" "a.out"
|
||||
|
||||
stderr: None
|
||||
retcode: 0
|
||||
|
||||
|
||||
runCmd: file /Volumes/data/lldb/svn/trunk/test/settings/a.out
|
||||
output: Current executable set to '/Volumes/data/lldb/svn/trunk/test/settings/a.out' (x86_64).
|
||||
|
||||
|
||||
runCmd: settings set target.process.output-path 'stdout.txt'
|
||||
output:
|
||||
|
||||
runCmd: settings show target.process.output-path
|
||||
output: target.process.output-path (string) = 'stdout.txt'
|
||||
|
||||
|
||||
Expecting start string: target.process.output-path (string) = 'stdout.txt'
|
||||
Matched
|
||||
|
||||
runCmd: run
|
||||
output: Process 43533 launched: '/Volumes/data/lldb/svn/trunk/test/settings/a.out' (x86_64)
|
||||
|
||||
|
||||
FAIL
|
||||
|
||||
runCmd: process kill
|
||||
check of return status not required
|
||||
runCmd failed!
|
||||
error: Process must be launched.
|
||||
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "/Volumes/data/lldb/svn/trunk/test/settings/TestSettings.py", line 125, in test_set_output_path
|
||||
"'stdout.txt' exists due to target.process.output-path.")
|
||||
AssertionError: False is not True : 'stdout.txt' exists due to target.process.output-path.
|
||||
|
||||
|
||||
@@ -1,309 +0,0 @@
|
||||
Let's pick test/settings/TestSettings.py as our example. First, notice the file
|
||||
name "TestSettings.py", the Test*.py pattern is the default mechanism that the
|
||||
test driver uses for discovery of tests. As to TestSettings.py, it defines a
|
||||
class:
|
||||
|
||||
class SettingsCommandTestCase(TestBase):
|
||||
|
||||
derived from TestBase, which is defined in test/lldbtest.py and is itself
|
||||
derived from Python's unittest framework's TestCase class. See also
|
||||
http://docs.python.org/library/unittest.html for more details.
|
||||
|
||||
To just run the TestSettings.py test, chdir to the lldb test directory, and then
|
||||
type the following command:
|
||||
|
||||
/Volumes/data/lldb/svn/trunk/test $ ./dotest.py settings
|
||||
----------------------------------------------------------------------
|
||||
Collected 6 tests
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 6 tests in 8.699s
|
||||
|
||||
OK (expected failures=1)
|
||||
/Volumes/data/lldb/svn/trunk/test $
|
||||
|
||||
Pass '-v' option to the test driver to also output verbose descriptions of the
|
||||
individual test cases and their test status:
|
||||
|
||||
/Volumes/data/lldb/svn/trunk/test $ ./dotest.py -v settings
|
||||
----------------------------------------------------------------------
|
||||
Collected 6 tests
|
||||
|
||||
test_set_auto_confirm (TestSettings.SettingsCommandTestCase)
|
||||
Test that after 'set auto-confirm true', manual confirmation should not kick in. ... ok
|
||||
test_set_output_path (TestSettings.SettingsCommandTestCase)
|
||||
Test that setting target.process.output-path for the launched process works. ... expected failure
|
||||
test_set_prompt (TestSettings.SettingsCommandTestCase)
|
||||
Test that 'set prompt' actually changes the prompt. ... ok
|
||||
test_set_term_width (TestSettings.SettingsCommandTestCase)
|
||||
Test that 'set term-width' actually changes the term-width. ... ok
|
||||
test_with_dsym (TestSettings.SettingsCommandTestCase)
|
||||
Test that run-args and env-vars are passed to the launched process. ... ok
|
||||
test_with_dwarf (TestSettings.SettingsCommandTestCase)
|
||||
Test that run-args and env-vars are passed to the launched process. ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 6 tests in 5.735s
|
||||
|
||||
OK (expected failures=1)
|
||||
/Volumes/data/lldb/svn/trunk/test $
|
||||
|
||||
Underneath, the '-v' option passes keyword argument verbosity=2 to the
|
||||
Python's unittest.TextTestRunner (see also
|
||||
http://docs.python.org/library/unittest.html#unittest.TextTestRunner). For very
|
||||
detailed descriptions about what's going on during the test, pass '-t' to the
|
||||
test driver, which asks the test driver to trace the commands executed and to
|
||||
display their output. For brevity, the '-t' output is not included here.
|
||||
|
||||
Notice the 'expected failures=1' message at the end of the run. This is because
|
||||
of a bug currently in lldb such that setting target.process.output-path to
|
||||
'stdout.txt' does not have any effect on the redirection of the standard output
|
||||
of the subsequent launched process. We are using unittest2 (a backport of new
|
||||
unittest features for Python 2.4-2.6) to decorate (mark) the particular test
|
||||
method as such:
|
||||
|
||||
@unittest2.expectedFailure
|
||||
# rdar://problem/8435794
|
||||
# settings set target.process.output-path does not seem to work
|
||||
def test_set_output_path(self):
|
||||
|
||||
See http://pypi.python.org/pypi/unittest2 for more details.
|
||||
|
||||
Now let's look inside the test method:
|
||||
|
||||
def test_set_output_path(self):
|
||||
"""Test that setting target.process.output-path for the launched process works."""
|
||||
self.buildDefault()
|
||||
|
||||
exe = os.path.join(os.getcwd(), "a.out")
|
||||
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
|
||||
|
||||
# Set the output-path and verify it is set.
|
||||
self.runCmd("settings set target.process.output-path 'stdout.txt'")
|
||||
self.expect("settings show target.process.output-path",
|
||||
startstr = "target.process.output-path (string) = 'stdout.txt'")
|
||||
|
||||
self.runCmd("run", RUN_SUCCEEDED)
|
||||
|
||||
# The 'stdout.txt' file should now exist.
|
||||
self.assertTrue(os.path.isfile("stdout.txt"),
|
||||
"'stdout.txt' exists due to target.process.output-path.")
|
||||
|
||||
# Read the output file produced by running the program.
|
||||
with open('stdout.txt', 'r') as f:
|
||||
output = f.read()
|
||||
|
||||
self.expect(output, exe=False,
|
||||
startstr = "This message should go to standard out.")
|
||||
|
||||
The self.buildDefault() statement is used to build a default binary for this
|
||||
test instance. For this particular test case, since we don't really care what
|
||||
debugging format is used, we instruct the build subsystem to build the default
|
||||
binary for us. The base class TestBase has defined three instance methods:
|
||||
|
||||
def buildDefault(self, architecture=None, compiler=None, dictionary=None):
|
||||
"""Platform specific way to build the default binaries."""
|
||||
module = __import__(sys.platform)
|
||||
if not module.buildDefault(self, architecture, compiler, dictionary):
|
||||
raise Exception("Don't know how to build default binary")
|
||||
|
||||
def buildDsym(self, architecture=None, compiler=None, dictionary=None):
|
||||
"""Platform specific way to build binaries with dsym info."""
|
||||
module = __import__(sys.platform)
|
||||
if not module.buildDsym(self, architecture, compiler, dictionary):
|
||||
raise Exception("Don't know how to build binary with dsym")
|
||||
|
||||
def buildDwarf(self, architecture=None, compiler=None, dictionary=None):
|
||||
"""Platform specific way to build binaries with dwarf maps."""
|
||||
module = __import__(sys.platform)
|
||||
if not module.buildDwarf(self, architecture, compiler, dictionary):
|
||||
raise Exception("Don't know how to build binary with dwarf")
|
||||
|
||||
And the test/plugins/darwin.py provides the implementation for all three build
|
||||
methods using the makefile mechanism. We envision that linux plugin can use a
|
||||
similar approach to accomplish the task of building the binaries.
|
||||
|
||||
Mac OS X provides an additional way to manipulate archived DWARF debug symbol
|
||||
files and produces dSYM files. The buildDsym() instance method is used by the
|
||||
test method to build the binary with dsym info. For an example of this,
|
||||
see test/array_types/TestArrayTypes.py:
|
||||
|
||||
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
|
||||
def test_with_dsym_and_run_command(self):
|
||||
"""Test 'frame variable var_name' on some variables with array types."""
|
||||
self.buildDsym()
|
||||
self.array_types()
|
||||
|
||||
This method is decorated with a skipUnless decorator so that it will only gets
|
||||
included into the test suite if the platform it is running on is 'darwin', aka
|
||||
Mac OS X.
|
||||
|
||||
Type 'man dsymutil' for more details.
|
||||
|
||||
After the binary is built, it is time to specify the file to be used as the main
|
||||
executable by lldb:
|
||||
|
||||
exe = os.path.join(os.getcwd(), "a.out")
|
||||
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
|
||||
|
||||
This is where the attribute assignment:
|
||||
|
||||
class SettingsCommandTestCase(TestBase):
|
||||
|
||||
mydir = "settings"
|
||||
|
||||
which happens right after the SettingsCommandTestCase class declaration comes
|
||||
into place. It specifies the relative directory to the top level 'test' so that
|
||||
the test harness can change its working directory in order to find the
|
||||
executable as well as the source code files. The runCmd() method is defined in
|
||||
the TestBase base class (within test/lldbtest.py) and its purpose is to pass the
|
||||
specified command to the lldb command interpreter. It's like you're typing the
|
||||
command within an interactive lldb session.
|
||||
|
||||
The CURRENT_EXECUTABLE_SET is an assert message defined in the lldbtest module
|
||||
so that it can be reused from other test modules.
|
||||
|
||||
By default, the runCmd() is going to check the return status of the command
|
||||
execution and fails the test if it is not a success. The assert message, in our
|
||||
case CURRENT_EXECUTABLE_SET, is used in the exception printout if this happens.
|
||||
|
||||
There are cases when we don't care about the return status from the command
|
||||
execution. This can be accomplished by passing the keyword argument pair
|
||||
'check=False' to the method.
|
||||
|
||||
After the current executable is set, we'll then execute two more commands:
|
||||
|
||||
# Set the output-path and verify it is set.
|
||||
self.runCmd("settings set target.process.output-path 'stdout.txt'")
|
||||
self.expect("settings show target.process.output-path",
|
||||
SETTING_MSG("target.process.output-path"),
|
||||
startstr = "target.process.output-path (string) = 'stdout.txt'")
|
||||
|
||||
The first uses the 'settings set' command to set the static setting
|
||||
target.process.output-path to be 'stdout.txt', instead of the default
|
||||
'/dev/stdout'. We then immediately issue a 'settings show' command to check
|
||||
that, indeed, the setting did take place. Notice that we use a new method
|
||||
expect() to accomplish the task, which in effect issues a runCmd() behind the
|
||||
door and grabs the output from the command execution and expects to match the
|
||||
start string of the output against what we pass in as the value of the keyword
|
||||
argument pair:
|
||||
|
||||
startstr = "target.process.output-path (string) = 'stdout.txt'"
|
||||
|
||||
Take a look at TestBase.expect() within lldbtest.py for more details. Among
|
||||
other things, it can also match against a list of regexp patterns as well as a
|
||||
list of sub strings. And it can also perform negative matching, i.e., instead
|
||||
of expecting something from the output of command execution, it can perform the
|
||||
action of 'not expecting' something.
|
||||
|
||||
This will launch/run the program:
|
||||
|
||||
self.runCmd("run", RUN_SUCCEEDED)
|
||||
|
||||
And this asserts that the file 'stdout.txt' should be present after running the
|
||||
program.
|
||||
|
||||
# The 'stdout.txt' file should now exist.
|
||||
self.assertTrue(os.path.isfile("stdout.txt"),
|
||||
"'stdout.txt' exists due to target.process.output-path.")
|
||||
|
||||
Also take a look at main.cpp which emits some message to the stdout. Now, if we
|
||||
pass this assertion, it's time to examine the contents of the file to make sure
|
||||
it contains the same message as programmed in main.cpp:
|
||||
|
||||
# Read the output file produced by running the program.
|
||||
with open('stdout.txt', 'r') as f:
|
||||
output = f.read()
|
||||
|
||||
self.expect(output, exe=False,
|
||||
startstr = "This message should go to standard out.")
|
||||
|
||||
We open the file and read its contents into output, then issue an expect()
|
||||
method. The 'exe=False' keyword argument pair tells expect() that don't try to
|
||||
execute the first arg as a command at all. Instead, treat it as a string to
|
||||
match against whatever is thrown in as keyword argument pairs!
|
||||
|
||||
There are also other test methods present in the TestSettings.py mode:
|
||||
test_set_prompt(), test_set_term_width(), test_set_auto_confirm(),
|
||||
test_with_dsym(), and test_with_dwarf(). We are using the default test loader
|
||||
from unittest framework, which uses the 'test' method name prefix to identify
|
||||
test methods automatically.
|
||||
|
||||
This finishes the walkthrough of the test method test_set_output_path(self).
|
||||
Before we say goodbye, notice the little method definition at the top of the
|
||||
file:
|
||||
|
||||
@classmethod
|
||||
def classCleanup(cls):
|
||||
system(["/bin/sh", "-c", "rm -f output.txt"])
|
||||
system(["/bin/sh", "-c", "rm -f stdout.txt"])
|
||||
|
||||
This is a classmethod (as shown by the @classmethod decorator) which allows the
|
||||
individual test class to perform cleanup actions after the test harness finishes
|
||||
with the particular test class. This is part of the so-called test fixture in
|
||||
the unittest framework. From http://docs.python.org/library/unittest.html:
|
||||
|
||||
A test fixture represents the preparation needed to perform one or more tests,
|
||||
and any associate cleanup actions. This may involve, for example, creating
|
||||
temporary or proxy databases, directories, or starting a server process.
|
||||
|
||||
The TestBase class uses such fixture with setUp(self), tearDown(self),
|
||||
setUpClass(cls), and tearDownClass(cls). And within teraDownClass(cls), it
|
||||
checks whether the current class has an attribute named 'classCleanup', and
|
||||
executes as a method if present. In this particular case, the classCleanup()
|
||||
calls a utility function system() defined in lldbtest.py in order to remove the
|
||||
files created by running the program as the tests are executed.
|
||||
|
||||
This system() function uses the Python subprocess module to spawn the process
|
||||
and to retrieve its results. If the test instance passes the keyword argument
|
||||
pair 'sender=self', the detailed command execution through the operating system
|
||||
also gets recorded in a session object. If the test instance fails or errors,
|
||||
the session info automatically gets dumped to a file grouped under a directory
|
||||
named after the timestamp of the particular test suite run.
|
||||
|
||||
For simple cases, look for the timestamp directory in the same directory of the
|
||||
test driver program dotest.py. For example, if we comment out the
|
||||
@expectedFailure decorator for TestSettings.py, and then run the test module:
|
||||
|
||||
/Volumes/data/lldb/svn/trunk/test $ ./dotest.py -v settings
|
||||
----------------------------------------------------------------------
|
||||
Collected 6 tests
|
||||
|
||||
test_set_auto_confirm (TestSettings.SettingsCommandTestCase)
|
||||
Test that after 'set auto-confirm true', manual confirmation should not kick in. ... ok
|
||||
test_set_output_path (TestSettings.SettingsCommandTestCase)
|
||||
Test that setting target.process.output-path for the launched process works. ... FAIL
|
||||
test_set_prompt (TestSettings.SettingsCommandTestCase)
|
||||
Test that 'set prompt' actually changes the prompt. ... ok
|
||||
test_set_term_width (TestSettings.SettingsCommandTestCase)
|
||||
Test that 'set term-width' actually changes the term-width. ... ok
|
||||
test_with_dsym (TestSettings.SettingsCommandTestCase)
|
||||
Test that run-args and env-vars are passed to the launched process. ... ok
|
||||
test_with_dwarf (TestSettings.SettingsCommandTestCase)
|
||||
Test that run-args and env-vars are passed to the launched process. ... ok
|
||||
|
||||
======================================================================
|
||||
FAIL: test_set_output_path (TestSettings.SettingsCommandTestCase)
|
||||
Test that setting target.process.output-path for the launched process works.
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/Volumes/data/lldb/svn/trunk/test/settings/TestSettings.py", line 125, in test_set_output_path
|
||||
"'stdout.txt' exists due to target.process.output-path.")
|
||||
AssertionError: False is not True : 'stdout.txt' exists due to target.process.output-path.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 6 tests in 8.219s
|
||||
|
||||
FAILED (failures=1)
|
||||
/Volumes/data/lldb/svn/trunk/test $ ls 2010-10-19-14:10:49.059609
|
||||
|
||||
NOTE: This directory name has been changed to not contain the ':' character
|
||||
which is not allowed in windows platforms. We'll change the ':' to '_'
|
||||
and get rid of the microsecond resolution by modifying the test driver.
|
||||
|
||||
TestSettings.SettingsCommandTestCase.test_set_output_path.log
|
||||
/Volumes/data/lldb/svn/trunk/test $
|
||||
|
||||
We get one failure and a timestamp directory 2010-10-19-14:10:49.059609.
|
||||
For education purposes, the directory and its contents are reproduced here in
|
||||
the same directory as the current file.
|
||||
@@ -1,93 +0,0 @@
|
||||
This document attempts to point out some best practices that prove to be helpful
|
||||
when building new test cases in the tot/test directory. Everyone is welcomed to
|
||||
add/modify contents into this file.
|
||||
|
||||
o Do not use hard-coded line numbers in your test case. Instead, try to tag the
|
||||
line with some distinguishing pattern, and use the function line_number()
|
||||
defined in lldbtest.py which takes filename and string_to_match as arguments
|
||||
and returns the line number.
|
||||
|
||||
As an example, take a look at test/breakpoint_conditions/main.c which has these
|
||||
two lines:
|
||||
|
||||
return c(val); // Find the line number of c's parent call here.
|
||||
|
||||
and
|
||||
|
||||
return val + 3; // Find the line number of function "c" here.
|
||||
|
||||
The Python test case TestBreakpointConditions.py uses the comment strings to
|
||||
find the line numbers during setUp(self) and use them later on to verify that
|
||||
the correct breakpoint is being stopped on and that its parent frame also has
|
||||
the correct line number as intended through the breakpoint condition.
|
||||
|
||||
o Take advantage of the unittest framework's decorator features to properly
|
||||
mark your test class or method for platform-specific tests.
|
||||
|
||||
As an example, take a look at test/forward/TestForwardDeclaration.py which has
|
||||
these lines:
|
||||
|
||||
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
|
||||
def test_with_dsym_and_run_command(self):
|
||||
"""Display *bar_ptr when stopped on a function with forward declaration of struct bar."""
|
||||
self.buildDsym()
|
||||
self.forward_declaration()
|
||||
|
||||
This tells the test harness that unless we are running "darwin", the test should
|
||||
be skipped. This is because we are asking to build the binaries with dsym debug
|
||||
info, which is only available on the darwin platforms.
|
||||
|
||||
o Cleanup after yourself. A classic example of this can be found in test/types/
|
||||
TestFloatTypes.py:
|
||||
|
||||
def test_float_types_with_dsym(self):
|
||||
"""Test that float-type variables are displayed correctly."""
|
||||
d = {'CXX_SOURCES': 'float.cpp'}
|
||||
self.buildDsym(dictionary=d)
|
||||
self.setTearDownCleanup(dictionary=d)
|
||||
self.float_type()
|
||||
|
||||
...
|
||||
|
||||
def test_double_type_with_dsym(self):
|
||||
"""Test that double-type variables are displayed correctly."""
|
||||
d = {'CXX_SOURCES': 'double.cpp'}
|
||||
self.buildDsym(dictionary=d)
|
||||
self.setTearDownCleanup(dictionary=d)
|
||||
self.double_type()
|
||||
|
||||
This tests different data structures composed of float types to verify that what
|
||||
the debugger prints out matches what the compiler does for different variables
|
||||
of these types. We're using a dictionary to pass the build parameters to the
|
||||
build system. After a particular test instance is done, it is a good idea to
|
||||
clean up the files built. This eliminates the chance that some leftover files
|
||||
can interfere with the build phase for the next test instance and render it
|
||||
invalid.
|
||||
|
||||
TestBase.setTearDownCleanup(self, dictionary) defined in lldbtest.py is created
|
||||
to cope with this use case by taking the same build parameters in order to do
|
||||
the cleanup when we are finished with a test instance, during
|
||||
TestBase.tearDown(self).
|
||||
|
||||
o Class-wise cleanup after yourself.
|
||||
|
||||
TestBase.tearDownClass(cls) provides a mechanism to invoke the platform-specific
|
||||
cleanup after finishing with a test class. A test class can have more than one
|
||||
test methods, so the tearDownClass(cls) method gets run after all the test
|
||||
methods have been executed by the test harness.
|
||||
|
||||
The default cleanup action performed by the plugins/darwin.py module invokes the
|
||||
"make clean" os command.
|
||||
|
||||
If this default cleanup is not enough, individual class can provide an extra
|
||||
cleanup hook with a class method named classCleanup , for example,
|
||||
in test/breakpoint_command/TestBreakpointCommand.py:
|
||||
|
||||
@classmethod
|
||||
def classCleanup(cls):
|
||||
system(["/bin/sh", "-c", "rm -f output.txt"])
|
||||
|
||||
The 'output.txt' file gets generated during the test run, so it makes sense to
|
||||
explicitly spell out the action in the same TestBreakpointCommand.py file to do
|
||||
the cleanup instead of artificially adding it as part of the default cleanup
|
||||
action which serves to cleanup those intermediate and a.out files.
|
||||
@@ -1,31 +0,0 @@
|
||||
Files in this directory:
|
||||
|
||||
o importcmd.py:
|
||||
|
||||
Python module which provides implementation for the 'import' command.
|
||||
|
||||
o README:
|
||||
|
||||
The file you are reading now.
|
||||
|
||||
================================================================================
|
||||
The import command defined by importcmd.py can be used in LLDB to load a Python
|
||||
module given its full pathname.
|
||||
The command works by extending Python's sys.path lookup to include the path to
|
||||
the module to be imported when required, and then going through the language
|
||||
ordinary 'import' mechanism. In this respect, modules imported from LLDB command
|
||||
line should not be distinguishable from those imported using the script interpreter.
|
||||
The following terminal output shows an interaction with lldb using this new command.
|
||||
|
||||
Enrico-Granatas-MacBook-Pro:Debug enricogranata$ ./lldb
|
||||
(lldb) script import importcmd
|
||||
(lldb) command script add import -f importcmd.pyimport_cmd
|
||||
(lldb) import ../demo.py
|
||||
(lldb) script demo.test_function('hello world')
|
||||
I am a Python function that says hello world
|
||||
(lldb) quit
|
||||
Enrico-Granatas-MacBook-Pro:Debug enricogranata$
|
||||
|
||||
Of course, the commands to import the importcmd.py module and to define the import
|
||||
command, can be included in the .lldbinit file to make this feature available at
|
||||
debugger startup
|
||||
@@ -1,30 +0,0 @@
|
||||
import sys,os,lldb
|
||||
def check_has_dir_in_path(dirname):
|
||||
return sys.path.__contains__(dirname);
|
||||
|
||||
def ensure_has_dir_in_path(dirname):
|
||||
dirname = os.path.abspath(dirname)
|
||||
if not (check_has_dir_in_path(dirname)):
|
||||
sys.path.append(dirname);
|
||||
|
||||
def do_import(debugger,modname):
|
||||
if (len(modname) > 4 and modname[-4:] == '.pyc'):
|
||||
modname = modname[:-4]
|
||||
if (len(modname) > 3 and modname[-3:] == '.py'):
|
||||
modname = modname[:-3]
|
||||
debugger.HandleCommand("script import " + modname)
|
||||
|
||||
def pyimport_cmd(debugger, args, result, dict):
|
||||
"""Import a Python module given its full path"""
|
||||
if args == "":
|
||||
return "no module path given";
|
||||
if not (os.sep in args):
|
||||
modname = args
|
||||
ensure_has_dir_in_path('.')
|
||||
else:
|
||||
endofdir = args.rfind(os.sep)
|
||||
modname = args[endofdir+1:]
|
||||
args = args[0:endofdir]
|
||||
ensure_has_dir_in_path(args)
|
||||
do_import(debugger,modname)
|
||||
return None
|
||||
@@ -1,7 +0,0 @@
|
||||
script import os, sys
|
||||
# So that ~/utils.py takes precedence.
|
||||
script sys.path[:0] = [os.path.expanduser('~')]
|
||||
script import utils
|
||||
command alias pwd script print os.getcwd()
|
||||
command script add -f utils.chdir cd
|
||||
command script add -f utils.system system
|
||||
@@ -1,41 +0,0 @@
|
||||
Files in this directory:
|
||||
|
||||
o .lldbinit:
|
||||
|
||||
An example lldb init file that imports the utils.py module and adds the
|
||||
following commands: 'pwd', 'cd', and 'system'.
|
||||
|
||||
o utils.py:
|
||||
|
||||
Python module which provides implementation for the 'cd' and 'system' commands.
|
||||
|
||||
o README:
|
||||
|
||||
The file you are reading now.
|
||||
|
||||
================================================================================
|
||||
The following terminal output shows an interaction with lldb using the .lldbinit
|
||||
and the utils.py files which are located in my HOME directory. The lldb init
|
||||
file imports the utils Python module and adds the 'pwd', 'cd', and 'system'
|
||||
commands.
|
||||
|
||||
Johnnys-MacBook-Pro:multiple_threads johnny$ pwd
|
||||
/Volumes/data/lldb/svn/trunk/test/functionalities/watchpoint/multiple_threads
|
||||
Johnnys-MacBook-Pro:multiple_threads johnny$ lldb
|
||||
(lldb) pwd
|
||||
/Volumes/data/lldb/svn/trunk/test/functionalities/watchpoint/multiple_threads
|
||||
(lldb) cd ..
|
||||
Current working directory: /Volumes/data/lldb/svn/trunk/test/functionalities/watchpoint
|
||||
(lldb) help system
|
||||
|
||||
Execute the command (a string) in a subshell.
|
||||
Syntax: system
|
||||
(lldb) system ls -l
|
||||
total 0
|
||||
drwxr-xr-x 7 johnny admin 238 Oct 11 17:24 hello_watchlocation
|
||||
drwxr-xr-x 7 johnny admin 238 Oct 11 17:24 hello_watchpoint
|
||||
drwxr-xr-x 7 johnny admin 238 Oct 11 17:24 multiple_threads
|
||||
drwxr-xr-x 7 johnny admin 238 Oct 11 17:24 watchpoint_commands
|
||||
|
||||
retcode: 0
|
||||
(lldb)
|
||||
@@ -1,51 +0,0 @@
|
||||
"""Utility for changing directories and execution of commands in a subshell."""
|
||||
|
||||
import os, shlex, subprocess
|
||||
|
||||
# Store the previous working directory for the 'cd -' command.
|
||||
class Holder:
|
||||
"""Holds the _prev_dir_ class attribute for chdir() function."""
|
||||
_prev_dir_ = None
|
||||
|
||||
@classmethod
|
||||
def prev_dir(cls):
|
||||
return cls._prev_dir_
|
||||
|
||||
@classmethod
|
||||
def swap(cls, dir):
|
||||
cls._prev_dir_ = dir
|
||||
|
||||
def chdir(debugger, args, result, dict):
|
||||
"""
|
||||
Change the working directory, or cd to ${HOME}.
|
||||
You can also issue 'cd -' to change to the previous working directory.
|
||||
"""
|
||||
new_dir = args.strip()
|
||||
if not new_dir:
|
||||
new_dir = os.path.expanduser('~')
|
||||
elif new_dir == '-':
|
||||
if not Holder.prev_dir():
|
||||
# Bad directory, not changing.
|
||||
print "bad directory, not changing"
|
||||
return
|
||||
else:
|
||||
new_dir = Holder.prev_dir()
|
||||
|
||||
Holder.swap(os.getcwd())
|
||||
os.chdir(new_dir)
|
||||
print "Current working directory: %s" % os.getcwd()
|
||||
|
||||
def system(debugger, command_line, result, dict):
|
||||
"""Execute the command (a string) in a subshell."""
|
||||
args = shlex.split(command_line)
|
||||
process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output, error = process.communicate()
|
||||
retcode = process.poll()
|
||||
if output and error:
|
||||
print "stdout=>\n", output
|
||||
print "stderr=>\n", error
|
||||
elif output:
|
||||
print output
|
||||
elif error:
|
||||
print error
|
||||
print "retcode:", retcode
|
||||
@@ -1,105 +0,0 @@
|
||||
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lldb/API/SBBlock.h"
|
||||
#include "lldb/API/SBCompileUnit.h"
|
||||
#include "lldb/API/SBDebugger.h"
|
||||
#include "lldb/API/SBFunction.h"
|
||||
#include "lldb/API/SBModule.h"
|
||||
#include "lldb/API/SBSymbol.h"
|
||||
#include "lldb/API/SBTarget.h"
|
||||
#include "lldb/API/SBThread.h"
|
||||
#include "lldb/API/SBProcess.h"
|
||||
|
||||
using namespace lldb;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// This quick sample code shows how to create a debugger instance and
|
||||
// create an "i386" executable target. Then we can lookup the executable
|
||||
// module and resolve a file address into a section offset address,
|
||||
// and find all symbol context objects (if any) for that address:
|
||||
// compile unit, function, deepest block, line table entry and the
|
||||
// symbol.
|
||||
//----------------------------------------------------------------------
|
||||
int
|
||||
main (int argc, char const *argv[])
|
||||
{
|
||||
// Initialize LLDB
|
||||
SBDebugger::Initialize();
|
||||
|
||||
if (argc < 3)
|
||||
exit (1);
|
||||
|
||||
// The first argument is the file path we want to look something up in
|
||||
const char *exe_file_path = argv[1];
|
||||
// The second argument in the address that we want to lookup
|
||||
lldb::addr_t file_addr = strtoull (argv[2], NULL, 0);
|
||||
|
||||
// Make a file spec out of our executable path
|
||||
SBFileSpec exe_file_spec (exe_file_path);
|
||||
|
||||
// Create a debugger instance so we can create a target
|
||||
SBDebugger debugger (SBDebugger::Create());
|
||||
|
||||
if (debugger.IsValid())
|
||||
{
|
||||
// Create a target using the executable.
|
||||
SBTarget target (debugger.CreateTargetWithFileAndArch (exe_file_path, "i386"));
|
||||
if (target.IsValid())
|
||||
{
|
||||
// Find the executable module so we can do a lookup inside it
|
||||
SBModule module (target.FindModule (exe_file_spec));
|
||||
SBAddress addr;
|
||||
|
||||
// Take a file virtual address and resolve it to a section offset
|
||||
// address that can be used to do a symbol lookup by address
|
||||
if (module.ResolveFileAddress (file_addr, addr))
|
||||
{
|
||||
// We can resolve a section offset address in the module
|
||||
// and only ask for what we need. You can logical or together
|
||||
// bits from the SymbolContextItem enumeration found in
|
||||
// lldb-enumeration.h to request only what you want. Here we
|
||||
// are asking for everything.
|
||||
//
|
||||
// NOTE: the less you ask for, the less LLDB will parse as
|
||||
// LLDB does partial parsing on just about everything.
|
||||
SBSymbolContext symbol_context (module.ResolveSymbolContextForAddress (addr, eSymbolContextEverything));
|
||||
|
||||
SBCompileUnit comp_unit (symbol_context.GetCompileUnit());
|
||||
if (comp_unit.IsValid())
|
||||
{
|
||||
}
|
||||
SBFunction function (symbol_context.GetFunction());
|
||||
if (function.IsValid())
|
||||
{
|
||||
}
|
||||
SBBlock block (symbol_context.GetBlock());
|
||||
if (block.IsValid())
|
||||
{
|
||||
}
|
||||
SBLineEntry line_entry (symbol_context.GetLineEntry());
|
||||
if (line_entry.IsValid())
|
||||
{
|
||||
}
|
||||
SBSymbol symbol (symbol_context.GetSymbol());
|
||||
if (symbol.IsValid())
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Terminate LLDB
|
||||
SBDebugger::Terminate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Be sure to add the python path that points to the LLDB shared library.
|
||||
# On MacOSX csh, tcsh:
|
||||
# setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
|
||||
# On MacOSX sh, bash:
|
||||
# export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
import lldb
|
||||
import os
|
||||
import sys
|
||||
|
||||
def disassemble_instructions (insts):
|
||||
for i in insts:
|
||||
print i
|
||||
|
||||
def usage():
|
||||
print "Usage: disasm.py [-n name] executable-image"
|
||||
print " By default, it breaks at and disassembles the 'main' function."
|
||||
sys.exit(0)
|
||||
|
||||
if len(sys.argv) == 2:
|
||||
fname = 'main'
|
||||
exe = sys.argv[1]
|
||||
elif len(sys.argv) == 4:
|
||||
if sys.argv[1] != '-n':
|
||||
usage()
|
||||
else:
|
||||
fname = sys.argv[2]
|
||||
exe = sys.argv[3]
|
||||
else:
|
||||
usage()
|
||||
|
||||
# Create a new debugger instance
|
||||
debugger = lldb.SBDebugger.Create()
|
||||
|
||||
# When we step or continue, don't return from the function until the process
|
||||
# stops. We do this by setting the async mode to false.
|
||||
debugger.SetAsync (False)
|
||||
|
||||
# Create a target from a file and arch
|
||||
print "Creating a target for '%s'" % exe
|
||||
|
||||
target = debugger.CreateTargetWithFileAndArch (exe, lldb.LLDB_ARCH_DEFAULT)
|
||||
|
||||
if target:
|
||||
# If the target is valid set a breakpoint at main
|
||||
main_bp = target.BreakpointCreateByName (fname, target.GetExecutable().GetFilename());
|
||||
|
||||
print main_bp
|
||||
|
||||
# Launch the process. Since we specified synchronous mode, we won't return
|
||||
# from this function until we hit the breakpoint at main
|
||||
process = target.LaunchSimple (None, None, os.getcwd())
|
||||
|
||||
# Make sure the launch went ok
|
||||
if process:
|
||||
# Print some simple process info
|
||||
state = process.GetState ()
|
||||
print process
|
||||
if state == lldb.eStateStopped:
|
||||
# Get the first thread
|
||||
thread = process.GetThreadAtIndex (0)
|
||||
if thread:
|
||||
# Print some simple thread info
|
||||
print thread
|
||||
# Get the first frame
|
||||
frame = thread.GetFrameAtIndex (0)
|
||||
if frame:
|
||||
# Print some simple frame info
|
||||
print frame
|
||||
function = frame.GetFunction()
|
||||
# See if we have debug info (a function)
|
||||
if function:
|
||||
# We do have a function, print some info for the function
|
||||
print function
|
||||
# Now get all instructions for this function and print them
|
||||
insts = function.GetInstructions(target)
|
||||
disassemble_instructions (insts)
|
||||
else:
|
||||
# See if we have a symbol in the symbol table for where we stopped
|
||||
symbol = frame.GetSymbol();
|
||||
if symbol:
|
||||
# We do have a symbol, print some info for the symbol
|
||||
print symbol
|
||||
# Now get all instructions for this symbol and print them
|
||||
insts = symbol.GetInstructions(target)
|
||||
disassemble_instructions (insts)
|
||||
|
||||
registerList = frame.GetRegisters()
|
||||
print "Frame registers (size of register set = %d):" % registerList.GetSize()
|
||||
for value in registerList:
|
||||
#print value
|
||||
print "%s (number of children = %d):" % (value.GetName(), value.GetNumChildren())
|
||||
for child in value:
|
||||
print "Name: ", child.GetName(), " Value: ", child.GetValue()
|
||||
|
||||
print "Hit the breakpoint at main, enter to continue and wait for program to exit or 'Ctrl-D'/'quit' to terminate the program"
|
||||
next = sys.stdin.readline()
|
||||
if not next or next.rstrip('\n') == 'quit':
|
||||
print "Terminating the inferior process..."
|
||||
process.Kill()
|
||||
else:
|
||||
# Now continue to the program exit
|
||||
process.Continue()
|
||||
# When we return from the above function we will hopefully be at the
|
||||
# program exit. Print out some process info
|
||||
print process
|
||||
elif state == lldb.eStateExited:
|
||||
print "Didn't hit the breakpoint at main, program has exited..."
|
||||
else:
|
||||
print "Unexpected process state: %s, killing process..." % debugger.StateAsCString (state)
|
||||
process.Kill()
|
||||
|
||||
|
||||
|
||||
lldb.SBDebugger.Terminate()
|
||||
@@ -1,573 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Be sure to add the python path that points to the LLDB shared library.
|
||||
# On MacOSX csh, tcsh:
|
||||
# setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
|
||||
# On MacOSX sh, bash:
|
||||
# export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
import lldb
|
||||
import optparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
|
||||
PARSE_MODE_NORMAL = 0
|
||||
PARSE_MODE_THREAD = 1
|
||||
PARSE_MODE_IMAGES = 2
|
||||
PARSE_MODE_THREGS = 3
|
||||
PARSE_MODE_SYSTEM = 4
|
||||
|
||||
class CrashLog:
|
||||
"""Class that does parses darwin crash logs"""
|
||||
thread_state_regex = re.compile('^Thread ([0-9]+) crashed with')
|
||||
thread_regex = re.compile('^Thread ([0-9]+)([^:]*):(.*)')
|
||||
frame_regex = re.compile('^([0-9]+).*\t(0x[0-9a-fA-F]+) +(.*)')
|
||||
image_regex_uuid = re.compile('(0x[0-9a-fA-F]+)[- ]+(0x[0-9a-fA-F]+) +([^ ]+) +([^<]+)<([-0-9a-fA-F]+)> (.*)');
|
||||
image_regex_no_uuid = re.compile('(0x[0-9a-fA-F]+)[- ]+(0x[0-9a-fA-F]+) +([^ ]+) +([^/]+)/(.*)');
|
||||
empty_line_regex = re.compile('^$')
|
||||
|
||||
class Thread:
|
||||
"""Class that represents a thread in a darwin crash log"""
|
||||
def __init__(self, index):
|
||||
self.index = index
|
||||
self.frames = list()
|
||||
self.registers = dict()
|
||||
self.reason = None
|
||||
self.queue = None
|
||||
|
||||
def dump(self, prefix):
|
||||
print "%sThread[%u] %s" % (prefix, self.index, self.reason)
|
||||
if self.frames:
|
||||
print "%s Frames:" % (prefix)
|
||||
for frame in self.frames:
|
||||
frame.dump(prefix + ' ')
|
||||
if self.registers:
|
||||
print "%s Registers:" % (prefix)
|
||||
for reg in self.registers.keys():
|
||||
print "%s %-5s = %#16.16x" % (prefix, reg, self.registers[reg])
|
||||
|
||||
def did_crash(self):
|
||||
return self.reason != None
|
||||
|
||||
def __str__(self):
|
||||
s = "Thread[%u]" % self.index
|
||||
if self.reason:
|
||||
s += ' %s' % self.reason
|
||||
return s
|
||||
|
||||
class Frame:
|
||||
"""Class that represents a stack frame in a thread in a darwin crash log"""
|
||||
def __init__(self, index, pc, details):
|
||||
self.index = index
|
||||
self.pc = pc
|
||||
self.sym_ctx = None
|
||||
self.details = details
|
||||
|
||||
def __str__(self):
|
||||
return "[%2u] %#16.16x %s" % (self.index, self.pc, self.details)
|
||||
|
||||
def dump(self, prefix):
|
||||
print "%s%s" % (prefix, self)
|
||||
|
||||
class Image:
|
||||
"""Class that represents a binary images in a darwin crash log"""
|
||||
def __init__(self, text_addr_lo, text_addr_hi, ident, version, uuid, path):
|
||||
self.text_addr_lo = text_addr_lo
|
||||
self.text_addr_hi = text_addr_hi
|
||||
self.ident = ident
|
||||
self.version = version
|
||||
self.uuid = uuid
|
||||
self.path = path
|
||||
|
||||
def dump(self, prefix):
|
||||
print "%s%s" % (prefix, self)
|
||||
|
||||
def __str__(self):
|
||||
return "%#16.16x %s %s" % (self.text_addr_lo, self.uuid, self.path)
|
||||
|
||||
|
||||
def __init__(self, path):
|
||||
"""CrashLog constructor that take a path to a darwin crash log file"""
|
||||
self.path = path;
|
||||
self.info_lines = list()
|
||||
self.system_profile = list()
|
||||
self.threads = list()
|
||||
self.images = list()
|
||||
self.crashed_thread_idx = -1
|
||||
self.version = -1
|
||||
# With possible initial component of ~ or ~user replaced by that user's home directory.
|
||||
f = open(os.path.expanduser(self.path))
|
||||
self.file_lines = f.read().splitlines()
|
||||
parse_mode = PARSE_MODE_NORMAL
|
||||
thread = None
|
||||
for line in self.file_lines:
|
||||
# print line
|
||||
line_len = len(line)
|
||||
if line_len == 0:
|
||||
if thread:
|
||||
if parse_mode == PARSE_MODE_THREAD:
|
||||
if thread.index == self.crashed_thread_idx:
|
||||
thread.reason = ''
|
||||
if self.thread_exception:
|
||||
thread.reason += self.thread_exception
|
||||
if self.thread_exception_data:
|
||||
thread.reason += " (%s)" % self.thread_exception_data
|
||||
self.threads.append(thread)
|
||||
thread = None
|
||||
else:
|
||||
# only append an extra empty line if the previous line
|
||||
# in the info_lines wasn't empty
|
||||
if len(self.info_lines) > 0 and len(self.info_lines[-1]):
|
||||
self.info_lines.append(line)
|
||||
parse_mode = PARSE_MODE_NORMAL
|
||||
# print 'PARSE_MODE_NORMAL'
|
||||
elif parse_mode == PARSE_MODE_NORMAL:
|
||||
if line.startswith ('Process:'):
|
||||
(self.process_name, pid_with_brackets) = line[8:].strip().split()
|
||||
self.process_id = pid_with_brackets.strip('[]')
|
||||
elif line.startswith ('Path:'):
|
||||
self.process_path = line[5:].strip()
|
||||
elif line.startswith ('Identifier:'):
|
||||
self.process_identifier = line[11:].strip()
|
||||
elif line.startswith ('Version:'):
|
||||
(self.process_version, compatability_version) = line[8:].strip().split()
|
||||
self.process_compatability_version = compatability_version.strip('()')
|
||||
elif line.startswith ('Parent Process:'):
|
||||
(self.parent_process_name, pid_with_brackets) = line[15:].strip().split()
|
||||
self.parent_process_id = pid_with_brackets.strip('[]')
|
||||
elif line.startswith ('Exception Type:'):
|
||||
self.thread_exception = line[15:].strip()
|
||||
continue
|
||||
elif line.startswith ('Exception Codes:'):
|
||||
self.thread_exception_data = line[16:].strip()
|
||||
continue
|
||||
elif line.startswith ('Crashed Thread:'):
|
||||
self.crashed_thread_idx = int(line[15:].strip().split()[0])
|
||||
continue
|
||||
elif line.startswith ('Report Version:'):
|
||||
self.version = int(line[15:].strip())
|
||||
continue
|
||||
elif line.startswith ('System Profile:'):
|
||||
parse_mode = PARSE_MODE_SYSTEM
|
||||
continue
|
||||
elif (line.startswith ('Interval Since Last Report:') or
|
||||
line.startswith ('Crashes Since Last Report:') or
|
||||
line.startswith ('Per-App Interval Since Last Report:') or
|
||||
line.startswith ('Per-App Crashes Since Last Report:') or
|
||||
line.startswith ('Sleep/Wake UUID:') or
|
||||
line.startswith ('Anonymous UUID:')):
|
||||
# ignore these
|
||||
continue
|
||||
elif line.startswith ('Thread'):
|
||||
thread_state_match = self.thread_state_regex.search (line)
|
||||
if thread_state_match:
|
||||
thread_state_match = self.thread_regex.search (line)
|
||||
thread_idx = int(thread_state_match.group(1))
|
||||
parse_mode = PARSE_MODE_THREGS
|
||||
thread = self.threads[thread_idx]
|
||||
else:
|
||||
thread_match = self.thread_regex.search (line)
|
||||
if thread_match:
|
||||
# print 'PARSE_MODE_THREAD'
|
||||
parse_mode = PARSE_MODE_THREAD
|
||||
thread_idx = int(thread_match.group(1))
|
||||
thread = CrashLog.Thread(thread_idx)
|
||||
continue
|
||||
elif line.startswith ('Binary Images:'):
|
||||
parse_mode = PARSE_MODE_IMAGES
|
||||
continue
|
||||
self.info_lines.append(line.strip())
|
||||
elif parse_mode == PARSE_MODE_THREAD:
|
||||
frame_match = self.frame_regex.search(line)
|
||||
if frame_match:
|
||||
thread.frames.append (CrashLog.Frame(int(frame_match.group(1)), int(frame_match.group(2), 0), frame_match.group(3)))
|
||||
else:
|
||||
print "error: frame regex failed"
|
||||
elif parse_mode == PARSE_MODE_IMAGES:
|
||||
image_match = self.image_regex_uuid.search (line)
|
||||
if image_match:
|
||||
image = CrashLog.Image (int(image_match.group(1),0),
|
||||
int(image_match.group(2),0),
|
||||
image_match.group(3).strip(),
|
||||
image_match.group(4).strip(),
|
||||
image_match.group(5),
|
||||
image_match.group(6))
|
||||
self.images.append (image)
|
||||
else:
|
||||
image_match = self.image_regex_no_uuid.search (line)
|
||||
if image_match:
|
||||
image = CrashLog.Image (int(image_match.group(1),0),
|
||||
int(image_match.group(2),0),
|
||||
image_match.group(3).strip(),
|
||||
image_match.group(4).strip(),
|
||||
None,
|
||||
image_match.group(5))
|
||||
self.images.append (image)
|
||||
else:
|
||||
print "error: image regex failed for: %s" % line
|
||||
|
||||
elif parse_mode == PARSE_MODE_THREGS:
|
||||
stripped_line = line.strip()
|
||||
reg_values = stripped_line.split(' ')
|
||||
for reg_value in reg_values:
|
||||
(reg, value) = reg_value.split(': ')
|
||||
thread.registers[reg.strip()] = int(value, 0)
|
||||
elif parse_mode == PARSE_MODE_SYSTEM:
|
||||
self.system_profile.append(line)
|
||||
f.close()
|
||||
|
||||
def dump(self):
|
||||
print "Crash Log File: %s" % (self.path)
|
||||
print "\nThreads:"
|
||||
for thread in self.threads:
|
||||
thread.dump(' ')
|
||||
print "\nImages:"
|
||||
for image in self.images:
|
||||
image.dump(' ')
|
||||
|
||||
def disassemble_instructions (target, instructions, pc, insts_before_pc, insts_after_pc):
|
||||
lines = list()
|
||||
pc_index = -1
|
||||
comment_column = 50
|
||||
for inst_idx, inst in enumerate(instructions):
|
||||
inst_pc = inst.GetAddress().GetLoadAddress(target);
|
||||
if pc == inst_pc:
|
||||
pc_index = inst_idx
|
||||
mnemonic = inst.GetMnemonic (target)
|
||||
operands = inst.GetOperands (target)
|
||||
comment = inst.GetComment (target)
|
||||
#data = inst.GetData (target)
|
||||
lines.append ("%#16.16x: %8s %s" % (inst_pc, mnemonic, operands))
|
||||
if comment:
|
||||
line_len = len(lines[-1])
|
||||
if line_len < comment_column:
|
||||
lines[-1] += ' ' * (comment_column - line_len)
|
||||
lines[-1] += "; %s" % comment
|
||||
|
||||
if pc_index >= 0:
|
||||
if pc_index >= insts_before_pc:
|
||||
start_idx = pc_index - insts_before_pc
|
||||
else:
|
||||
start_idx = 0
|
||||
end_idx = pc_index + insts_after_pc
|
||||
if end_idx > inst_idx:
|
||||
end_idx = inst_idx
|
||||
for i in range(start_idx, end_idx+1):
|
||||
if i == pc_index:
|
||||
print ' -> ', lines[i]
|
||||
else:
|
||||
print ' ', lines[i]
|
||||
|
||||
def print_module_section_data (section):
|
||||
print section
|
||||
section_data = section.GetSectionData()
|
||||
if section_data:
|
||||
ostream = lldb.SBStream()
|
||||
section_data.GetDescription (ostream, section.GetFileAddress())
|
||||
print ostream.GetData()
|
||||
|
||||
def print_module_section (section, depth):
|
||||
print section
|
||||
|
||||
if depth > 0:
|
||||
num_sub_sections = section.GetNumSubSections()
|
||||
for sect_idx in range(num_sub_sections):
|
||||
print_module_section (section.GetSubSectionAtIndex(sect_idx), depth - 1)
|
||||
|
||||
def print_module_sections (module, depth):
|
||||
for sect in module.section_iter():
|
||||
print_module_section (sect, depth)
|
||||
|
||||
def print_module_symbols (module):
|
||||
for sym in module:
|
||||
print sym
|
||||
|
||||
def usage():
|
||||
print "Usage: lldb-symbolicate.py [-n name] executable-image"
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = optparse.OptionParser(description='A script that parses skinny and universal mach-o files.')
|
||||
parser.add_option('--arch', type='string', metavar='arch', dest='triple', help='specify one architecture or target triple')
|
||||
parser.add_option('--platform', type='string', metavar='platform', dest='platform', help='specify one platform by name')
|
||||
parser.add_option('--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
|
||||
parser.add_option('--interactive', action='store_true', dest='interactive', help='enable interactive mode', default=False)
|
||||
parser.add_option('--no-images', action='store_false', dest='show_images', help='don\'t show images in stack frames', default=True)
|
||||
parser.add_option('--no-dependents', action='store_false', dest='dependents', help='skip loading dependent modules', default=True)
|
||||
parser.add_option('--sections', action='store_true', dest='dump_sections', help='show module sections', default=False)
|
||||
parser.add_option('--symbols', action='store_true', dest='dump_symbols', help='show module symbols', default=False)
|
||||
parser.add_option('--image-list', action='store_true', dest='dump_image_list', help='show image list', default=False)
|
||||
parser.add_option('--debug-delay', type='int', dest='debug_delay', metavar='NSEC', help='pause for NSEC seconds for debugger', default=0)
|
||||
parser.add_option('--section-depth', type='int', dest='section_depth', help='set the section depth to use when showing sections', default=0)
|
||||
parser.add_option('--section-data', type='string', action='append', dest='sect_data_names', help='specify sections by name to display data for')
|
||||
parser.add_option('--address', type='int', action='append', dest='addresses', help='specify addresses to lookup')
|
||||
parser.add_option('--crash-log', type='string', action='append', dest='crash_log_files', help='specify crash log files to symbolicate')
|
||||
parser.add_option('--crashed-only', action='store_true', dest='crashed_only', help='only show the crashed thread', default=False)
|
||||
loaded_addresses = False
|
||||
(options, args) = parser.parse_args()
|
||||
if options.verbose:
|
||||
print 'options', options
|
||||
|
||||
if options.debug_delay > 0:
|
||||
print "Waiting %u seconds for debugger to attach..." % options.debug_delay
|
||||
time.sleep(options.debug_delay)
|
||||
|
||||
# Create a new debugger instance
|
||||
debugger = lldb.SBDebugger.Create()
|
||||
|
||||
# When we step or continue, don't return from the function until the process
|
||||
# stops. We do this by setting the async mode to false.
|
||||
debugger.SetAsync (False)
|
||||
error = lldb.SBError()
|
||||
|
||||
if options.crash_log_files:
|
||||
options.dependents = False
|
||||
for crash_log_file in options.crash_log_files:
|
||||
triple = "x86_64"
|
||||
crash_log = CrashLog(crash_log_file)
|
||||
#crash_log.dump()
|
||||
target = debugger.CreateTarget (crash_log.process_path, options.triple, options.platform, options.dependents, error);
|
||||
exe_module = target.GetModuleAtIndex(0)
|
||||
image_paths = list()
|
||||
for image in crash_log.images:
|
||||
if image.path == crash_log.process_path:
|
||||
module = exe_module
|
||||
else:
|
||||
module = target.AddModule (image.path, options.triple, image.uuid)
|
||||
if image.path in image_paths:
|
||||
print "warning: skipping %s loaded at %#16.16x duplicate entry (probably commpage)" % (image.path, image.text_addr_lo)
|
||||
else:
|
||||
image_paths.append(image.path)
|
||||
|
||||
if not module and image.uuid != module.GetUUIDString():
|
||||
if image.uuid:
|
||||
print "warning: couldn't locate %s %s" % (image.uuid, image.path)
|
||||
else:
|
||||
print "warning: couldn't locate %s" % (image.path)
|
||||
else:
|
||||
target.SetSectionLoadAddress (module.FindSection ("__TEXT"), image.text_addr_lo)
|
||||
for line in crash_log.info_lines:
|
||||
print line
|
||||
# Reconstruct inlined frames for all threads for anything that has debug info
|
||||
for thread in crash_log.threads:
|
||||
if options.crashed_only and thread.did_crash() == False:
|
||||
continue
|
||||
# start a new frame list that we will fixup for each thread
|
||||
new_thread_frames = list()
|
||||
# Iterate through all concrete frames for a thread and resolve
|
||||
# any parent frames of inlined functions
|
||||
for frame_idx, frame in enumerate(thread.frames):
|
||||
# Resolve the frame's pc into a section + offset address 'pc_addr'
|
||||
pc_addr = target.ResolveLoadAddress (frame.pc)
|
||||
# Check to see if we were able to resolve the address
|
||||
if pc_addr:
|
||||
# We were able to resolve the frame's PC into a section offset
|
||||
# address.
|
||||
|
||||
# Resolve the frame's PC value into a symbol context. A symbol
|
||||
# context can resolve a module, compile unit, function, block,
|
||||
# line table entry and/or symbol. If the frame has a block, then
|
||||
# we can look for inlined frames, which are represented by blocks
|
||||
# that have inlined information in them
|
||||
frame.sym_ctx = target.ResolveSymbolContextForAddress (pc_addr, lldb.eSymbolContextEverything);
|
||||
|
||||
# dump if the verbose option was specified
|
||||
if options.verbose:
|
||||
print "frame.pc = %#16.16x (file_addr = %#16.16x)" % (frame.pc, pc_addr.GetFileAddress())
|
||||
print "frame.pc_addr = ", pc_addr
|
||||
print "frame.sym_ctx = "
|
||||
print frame.sym_ctx
|
||||
print
|
||||
|
||||
# Append the frame we already had from the crash log to the new
|
||||
# frames list
|
||||
new_thread_frames.append(frame)
|
||||
|
||||
new_frame = CrashLog.Frame (frame.index, -1, None)
|
||||
|
||||
# Try and use the current frame's symbol context to calculate a
|
||||
# parent frame for an inlined function. If the curent frame is
|
||||
# inlined, it will return a valid symbol context for the parent
|
||||
# frame of the current inlined function
|
||||
parent_pc_addr = lldb.SBAddress()
|
||||
new_frame.sym_ctx = frame.sym_ctx.GetParentOfInlinedScope (pc_addr, parent_pc_addr)
|
||||
|
||||
# See if we were able to reconstruct anything?
|
||||
while new_frame.sym_ctx:
|
||||
# We have a parent frame of an inlined frame, create a new frame
|
||||
# Convert the section + offset 'parent_pc_addr' to a load address
|
||||
new_frame.pc = parent_pc_addr.GetLoadAddress(target)
|
||||
# push the new frame onto the new frame stack
|
||||
new_thread_frames.append (new_frame)
|
||||
# dump if the verbose option was specified
|
||||
if options.verbose:
|
||||
print "new_frame.pc = %#16.16x (%s)" % (new_frame.pc, parent_pc_addr)
|
||||
print "new_frame.sym_ctx = "
|
||||
print new_frame.sym_ctx
|
||||
print
|
||||
# Create another new frame in case we have multiple inlined frames
|
||||
prev_new_frame = new_frame
|
||||
new_frame = CrashLog.Frame (frame.index, -1, None)
|
||||
# Swap the addresses so we can try another inlined lookup
|
||||
pc_addr = parent_pc_addr;
|
||||
new_frame.sym_ctx = prev_new_frame.sym_ctx.GetParentOfInlinedScope (pc_addr, parent_pc_addr)
|
||||
# Replace our thread frames with our new list that includes parent
|
||||
# frames for inlined functions
|
||||
thread.frames = new_thread_frames
|
||||
# Now iterate through all threads and display our richer stack backtraces
|
||||
for thread in crash_log.threads:
|
||||
this_thread_crashed = thread.did_crash()
|
||||
if options.crashed_only and this_thread_crashed == False:
|
||||
continue
|
||||
print "%s" % thread
|
||||
prev_frame_index = -1
|
||||
for frame_idx, frame in enumerate(thread.frames):
|
||||
details = ' %s' % frame.details
|
||||
module = frame.sym_ctx.GetModule()
|
||||
instructions = None
|
||||
if module:
|
||||
module_basename = module.GetFileSpec().GetFilename();
|
||||
function_start_load_addr = -1
|
||||
function_name = None
|
||||
function = frame.sym_ctx.GetFunction()
|
||||
block = frame.sym_ctx.GetBlock()
|
||||
line_entry = frame.sym_ctx.GetLineEntry()
|
||||
symbol = frame.sym_ctx.GetSymbol()
|
||||
inlined_block = block.GetContainingInlinedBlock();
|
||||
if inlined_block:
|
||||
function_name = inlined_block.GetInlinedName();
|
||||
block_range_idx = inlined_block.GetRangeIndexForBlockAddress (target.ResolveLoadAddress (frame.pc))
|
||||
if block_range_idx < lldb.UINT32_MAX:
|
||||
block_range_start_addr = inlined_block.GetRangeStartAddress (block_range_idx)
|
||||
function_start_load_addr = block_range_start_addr.GetLoadAddress (target)
|
||||
else:
|
||||
function_start_load_addr = frame.pc
|
||||
if this_thread_crashed and frame_idx == 0:
|
||||
instructions = function.GetInstructions(target)
|
||||
elif function:
|
||||
function_name = function.GetName()
|
||||
function_start_load_addr = function.GetStartAddress().GetLoadAddress (target)
|
||||
if this_thread_crashed and frame_idx == 0:
|
||||
instructions = function.GetInstructions(target)
|
||||
elif symbol:
|
||||
function_name = symbol.GetName()
|
||||
function_start_load_addr = symbol.GetStartAddress().GetLoadAddress (target)
|
||||
if this_thread_crashed and frame_idx == 0:
|
||||
instructions = symbol.GetInstructions(target)
|
||||
|
||||
if function_name:
|
||||
# Print the function or symbol name and annotate if it was inlined
|
||||
inline_suffix = ''
|
||||
if inlined_block:
|
||||
inline_suffix = '[inlined] '
|
||||
else:
|
||||
inline_suffix = ' '
|
||||
if options.show_images:
|
||||
details = "%s%s`%s" % (inline_suffix, module_basename, function_name)
|
||||
else:
|
||||
details = "%s" % (function_name)
|
||||
# Dump the offset from the current function or symbol if it is non zero
|
||||
function_offset = frame.pc - function_start_load_addr
|
||||
if function_offset > 0:
|
||||
details += " + %u" % (function_offset)
|
||||
elif function_offset < 0:
|
||||
defaults += " %i (invalid negative offset, file a bug) " % function_offset
|
||||
# Print out any line information if any is available
|
||||
if line_entry.GetFileSpec():
|
||||
details += ' at %s' % line_entry.GetFileSpec().GetFilename()
|
||||
details += ':%u' % line_entry.GetLine ()
|
||||
column = line_entry.GetColumn()
|
||||
if column > 0:
|
||||
details += ':%u' % column
|
||||
|
||||
|
||||
# Only print out the concrete frame index if it changes.
|
||||
# if prev_frame_index != frame.index:
|
||||
# print "[%2u] %#16.16x %s" % (frame.index, frame.pc, details)
|
||||
# else:
|
||||
# print " %#16.16x %s" % (frame.pc, details)
|
||||
print "[%2u] %#16.16x %s" % (frame.index, frame.pc, details)
|
||||
prev_frame_index = frame.index
|
||||
if instructions:
|
||||
print
|
||||
disassemble_instructions (target, instructions, frame.pc, 4, 4)
|
||||
print
|
||||
|
||||
print
|
||||
|
||||
if options.dump_image_list:
|
||||
print "Binary Images:"
|
||||
for image in crash_log.images:
|
||||
print image
|
||||
else:
|
||||
for exe_file in args:
|
||||
|
||||
# Create a target from a file and arch
|
||||
print "Creating a target for '%s'" % exe_file
|
||||
|
||||
target = debugger.CreateTarget (exe_file, options.triple, options.platform, options.dependents, error);
|
||||
|
||||
if target:
|
||||
exe_module = None;
|
||||
module_count = target.GetNumModules();
|
||||
for module_idx in range(module_count):
|
||||
module = target.GetModuleAtIndex (module_idx)
|
||||
if module_idx == 0:
|
||||
exe_module = module
|
||||
print "module[%u] = %s" % (module_idx, module)
|
||||
|
||||
if options.dump_symbols:
|
||||
print_module_symbols (module)
|
||||
if options.dump_sections:
|
||||
print_module_sections (module, options.section_depth)
|
||||
if options.sect_data_names:
|
||||
for sect_name in options.sect_data_names:
|
||||
section = module.FindSection (sect_name)
|
||||
if section:
|
||||
print_module_section_data (section)
|
||||
else:
|
||||
print "No section was found in '%s' named '%s'" % (module, sect_name)
|
||||
if options.addresses:
|
||||
for address in options.addresses:
|
||||
if loaded_addresses:
|
||||
so_address = target.ResolveLoadAddress (address)
|
||||
if so_address:
|
||||
print so_address
|
||||
so_address_sc = exe_module.ResolveSymbolContextForAddress (so_address, lldb.eSymbolContextEverything);
|
||||
print so_address_sc
|
||||
else:
|
||||
print "error: 0x%8.8x failed to resolve as a load address" % (address)
|
||||
else:
|
||||
so_address = exe_module.ResolveFileAddress (address)
|
||||
|
||||
if so_address:
|
||||
print so_address
|
||||
so_address_sc = exe_module.ResolveSymbolContextForAddress (so_address, lldb.eSymbolContextEverything);
|
||||
print so_address_sc
|
||||
else:
|
||||
print "error: 0x%8.8x failed to resolve as a file address in %s" % (address, exe_module)
|
||||
|
||||
# text_base_addr = 0x10000
|
||||
# load_addr = 0x10bb0
|
||||
# text_segment = exe_module.FindSection ("__TEXT")
|
||||
# if text_segment:
|
||||
# target.SetSectionLoadAddress (text_segment, text_base_addr)
|
||||
#
|
||||
# load_so_addr = target.ResolveLoadAddress (load_addr)
|
||||
#
|
||||
# if load_so_addr:
|
||||
# sc = target.ResolveSymbolContextForAddress (so_addr, lldb.eSymbolContextEverything);
|
||||
# print sc
|
||||
# else:
|
||||
# print "error: 0x%8.8x failed to resolve as a load address" % (load_addr)
|
||||
else:
|
||||
print "error: ", error
|
||||
|
||||
|
||||
lldb.SBDebugger.Terminate()
|
||||
|
||||
@@ -1,200 +0,0 @@
|
||||
//===-- dictionary.c ---------------------------------------------*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===---------------------------------------------------------------------===//
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct tree_node
|
||||
{
|
||||
const char *word;
|
||||
struct tree_node *left;
|
||||
struct tree_node *right;
|
||||
} tree_node;
|
||||
|
||||
/* Given a char*, returns a substring that starts at the first
|
||||
alphabet character and ends at the last alphabet character, i.e. it
|
||||
strips off beginning or ending quotes, punctuation, etc. */
|
||||
|
||||
char *
|
||||
strip (char **word)
|
||||
{
|
||||
char *start = *word;
|
||||
int len = strlen (start);
|
||||
char *end = start + len - 1;
|
||||
|
||||
while ((start < end) && (!isalpha (start[0])))
|
||||
start++;
|
||||
|
||||
while ((end > start) && (!isalpha (end[0])))
|
||||
end--;
|
||||
|
||||
if (start > end)
|
||||
return NULL;
|
||||
|
||||
end[1] = '\0';
|
||||
*word = start;
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
/* Given a binary search tree (sorted alphabetically by the word at
|
||||
each node), and a new word, inserts the word at the appropriate
|
||||
place in the tree. */
|
||||
|
||||
void
|
||||
insert (tree_node *root, char *word)
|
||||
{
|
||||
if (root == NULL)
|
||||
return;
|
||||
|
||||
int compare_value = strcmp (word, root->word);
|
||||
|
||||
if (compare_value == 0)
|
||||
return;
|
||||
|
||||
if (compare_value < 0)
|
||||
{
|
||||
if (root->left != NULL)
|
||||
insert (root->left, word);
|
||||
else
|
||||
{
|
||||
tree_node *new_node = (tree_node *) malloc (sizeof (tree_node));
|
||||
new_node->word = strdup (word);
|
||||
new_node->left = NULL;
|
||||
new_node->right = NULL;
|
||||
root->left = new_node;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (root->right != NULL)
|
||||
insert (root->right, word);
|
||||
else
|
||||
{
|
||||
tree_node *new_node = (tree_node *) malloc (sizeof (tree_node));
|
||||
new_node->word = strdup (word);
|
||||
new_node->left = NULL;
|
||||
new_node->right = NULL;
|
||||
root->right = new_node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Read in a text file and storea all the words from the file in a
|
||||
binary search tree. */
|
||||
|
||||
void
|
||||
populate_dictionary (tree_node **dictionary, char *filename)
|
||||
{
|
||||
FILE *in_file;
|
||||
char word[1024];
|
||||
|
||||
in_file = fopen (filename, "r");
|
||||
if (in_file)
|
||||
{
|
||||
while (fscanf (in_file, "%s", word) == 1)
|
||||
{
|
||||
char *new_word = (strdup (word));
|
||||
new_word = strip (&new_word);
|
||||
if (*dictionary == NULL)
|
||||
{
|
||||
tree_node *new_node = (tree_node *) malloc (sizeof (tree_node));
|
||||
new_node->word = new_word;
|
||||
new_node->left = NULL;
|
||||
new_node->right = NULL;
|
||||
*dictionary = new_node;
|
||||
}
|
||||
else
|
||||
insert (*dictionary, new_word);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a binary search tree and a word, search for the word
|
||||
in the binary search tree. */
|
||||
|
||||
int
|
||||
find_word (tree_node *dictionary, char *word)
|
||||
{
|
||||
if (!word || !dictionary)
|
||||
return 0;
|
||||
|
||||
int compare_value = strcmp (word, dictionary->word);
|
||||
|
||||
if (compare_value == 0)
|
||||
return 1;
|
||||
else if (compare_value < 0)
|
||||
return find_word (dictionary->left, word);
|
||||
else
|
||||
return find_word (dictionary->right, word);
|
||||
}
|
||||
|
||||
/* Print out the words in the binary search tree, in sorted order. */
|
||||
|
||||
void
|
||||
print_tree (tree_node *dictionary)
|
||||
{
|
||||
if (!dictionary)
|
||||
return;
|
||||
|
||||
if (dictionary->left)
|
||||
print_tree (dictionary->left);
|
||||
|
||||
printf ("%s\n", dictionary->word);
|
||||
|
||||
|
||||
if (dictionary->right)
|
||||
print_tree (dictionary->right);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
tree_node *dictionary = NULL;
|
||||
char buffer[1024];
|
||||
char *filename;
|
||||
int done = 0;
|
||||
|
||||
if (argc == 2)
|
||||
filename = argv[1];
|
||||
|
||||
if (!filename)
|
||||
return -1;
|
||||
|
||||
populate_dictionary (&dictionary, filename);
|
||||
fprintf (stdout, "Dictionary loaded.\nEnter search word: ");
|
||||
while (!done && fgets (buffer, sizeof(buffer), stdin))
|
||||
{
|
||||
char *word = buffer;
|
||||
int len = strlen (word);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
word[i] = tolower (word[i]);
|
||||
|
||||
if ((len > 0) && (word[len-1] == '\n'))
|
||||
{
|
||||
word[len-1] = '\0';
|
||||
len = len - 1;
|
||||
}
|
||||
|
||||
if (find_word (dictionary, word))
|
||||
fprintf (stdout, "Yes!\n");
|
||||
else
|
||||
fprintf (stdout, "No!\n");
|
||||
|
||||
fprintf (stdout, "Enter search word: ");
|
||||
}
|
||||
|
||||
fprintf (stdout, "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
"""
|
||||
# ===-- tree_utils.py ---------------------------------------*- Python -*-===//
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
# ===---------------------------------------------------------------------===//
|
||||
|
||||
tree_utils.py - A set of functions for examining binary
|
||||
search trees, based on the example search tree defined in
|
||||
dictionary.c. These functions contain calls to LLDB API
|
||||
functions, and assume that the LLDB Python module has been
|
||||
imported.
|
||||
|
||||
For a thorough explanation of how the DFS function works, and
|
||||
for more information about dictionary.c go to
|
||||
http://lldb.llvm.org/scripting.html
|
||||
"""
|
||||
|
||||
|
||||
def DFS (root, word, cur_path):
|
||||
"""
|
||||
Recursively traverse a binary search tree containing
|
||||
words sorted alphabetically, searching for a particular
|
||||
word in the tree. Also maintains a string representing
|
||||
the path from the root of the tree to the current node.
|
||||
If the word is found in the tree, return the path string.
|
||||
Otherwise return an empty string.
|
||||
|
||||
This function assumes the binary search tree is
|
||||
the one defined in dictionary.c It uses LLDB API
|
||||
functions to examine and traverse the tree nodes.
|
||||
"""
|
||||
|
||||
# Get pointer field values out of node 'root'
|
||||
|
||||
root_word_ptr = root.GetChildMemberWithName ("word")
|
||||
left_child_ptr = root.GetChildMemberWithName ("left")
|
||||
right_child_ptr = root.GetChildMemberWithName ("right")
|
||||
|
||||
# Get the word out of the word pointer and strip off
|
||||
# surrounding quotes (added by call to GetSummary).
|
||||
|
||||
root_word = root_word_ptr.GetSummary()
|
||||
end = len (root_word) - 1
|
||||
if root_word[0] == '"' and root_word[end] == '"':
|
||||
root_word = root_word[1:end]
|
||||
end = len (root_word) - 1
|
||||
if root_word[0] == '\'' and root_word[end] == '\'':
|
||||
root_word = root_word[1:end]
|
||||
|
||||
# Main depth first search
|
||||
|
||||
if root_word == word:
|
||||
return cur_path
|
||||
elif word < root_word:
|
||||
|
||||
# Check to see if left child is NULL
|
||||
|
||||
if left_child_ptr.GetValue() == None:
|
||||
return ""
|
||||
else:
|
||||
cur_path = cur_path + "L"
|
||||
return DFS (left_child_ptr, word, cur_path)
|
||||
else:
|
||||
|
||||
# Check to see if right child is NULL
|
||||
|
||||
if right_child_ptr.GetValue() == None:
|
||||
return ""
|
||||
else:
|
||||
cur_path = cur_path + "R"
|
||||
return DFS (right_child_ptr, word, cur_path)
|
||||
|
||||
|
||||
def tree_size (root):
|
||||
"""
|
||||
Recursively traverse a binary search tree, counting
|
||||
the nodes in the tree. Returns the final count.
|
||||
|
||||
This function assumes the binary search tree is
|
||||
the one defined in dictionary.c It uses LLDB API
|
||||
functions to examine and traverse the tree nodes.
|
||||
"""
|
||||
if (root.GetValue == None):
|
||||
return 0
|
||||
|
||||
if (int (root.GetValue(), 16) == 0):
|
||||
return 0
|
||||
|
||||
left_size = tree_size (root.GetChildAtIndex(1));
|
||||
right_size = tree_size (root.GetChildAtIndex(2));
|
||||
|
||||
total_size = left_size + right_size + 1
|
||||
return total_size
|
||||
|
||||
|
||||
def print_tree (root):
|
||||
"""
|
||||
Recursively traverse a binary search tree, printing out
|
||||
the words at the nodes in alphabetical order (the
|
||||
search order for the binary tree).
|
||||
|
||||
This function assumes the binary search tree is
|
||||
the one defined in dictionary.c It uses LLDB API
|
||||
functions to examine and traverse the tree nodes.
|
||||
"""
|
||||
if (root.GetChildAtIndex(1).GetValue() != None) and (int (root.GetChildAtIndex(1).GetValue(), 16) != 0):
|
||||
print_tree (root.GetChildAtIndex(1))
|
||||
|
||||
print root.GetChildAtIndex(0).GetSummary()
|
||||
|
||||
if (root.GetChildAtIndex(2).GetValue() != None) and (int (root.GetChildAtIndex(2).GetValue(), 16) != 0):
|
||||
print_tree (root.GetChildAtIndex(2))
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
type summary add -s "${var._M_dataplus._M_p}" std::string std::basic_string<char> "std::basic_string<char,std::char_traits<char>,std::allocator<char> >"
|
||||
type summary add -s "\"${var%@}\"" "NSString *"
|
||||
type summary add -s "${svar%#} items" -e -x std::map<
|
||||
type summary add -s "${svar%#} items" -e -x std::vector<
|
||||
type summary add -s "${svar%#} items" -e -x std::list<
|
||||
@@ -1,15 +0,0 @@
|
||||
type summary add -w lldb lldb_private::Error -s "Type: ${var.m_type%E}, Code: ${var.m_code}, Message: ${var.m_string}"
|
||||
type summary add -w lldb lldb_private::ConstString -s "${var.m_string}"
|
||||
type summary add -w lldb lldb_private::Language -s "${var.m_language%E}"
|
||||
type summary add -w lldb lldb_private::RegularExpression -s "${var.m_re}"
|
||||
type summary add -w lldb lldb_private::UserID -s "UserID(${var.m_uid})"
|
||||
type summary add -w lldb lldb_private::ValueObject -s "${var.m_name}"
|
||||
type summary add -w lldb lldb_private::ValueObjectSP -s "${var.ptr_.m_name}"
|
||||
type summary add -w lldb lldb_private::ValueObjectRegister -s "${var.m_reg_info.name}"
|
||||
type summary add -w lldb lldb_private::ClangExpression -s "{${var.m_expr_text}}"
|
||||
type summary add -w lldb lldb_private::CommandObject -s "Command name: ${var.m_cmd_name}"
|
||||
type summary add -w lldb lldb_private::Variable -s "${var.m_type.m_name} ${var.m_name}"
|
||||
type summary add -w lldb lldb_private::StopInfo -s "ID: ${var.m_stop_id}, ${var.m_description}"
|
||||
type summary add -w lldb lldb_private::FileSpec -s "file: ${var.m_filename} dir: ${var.m_directory}"
|
||||
type summary add -w lldb -v lldb::ConnectionStatus -s "[enum=${var%E} val=${var%i}]"
|
||||
# Where '-v' tells type summary not to show the value itself, but just use the summary format.
|
||||
@@ -1,237 +0,0 @@
|
||||
# synthetic children and summary provider for CFString
|
||||
# (and related NSString class)
|
||||
import lldb
|
||||
|
||||
def CFString_SummaryProvider (valobj,dict):
|
||||
provider = CFStringSynthProvider(valobj,dict);
|
||||
if provider.invalid == False:
|
||||
return '@'+provider.get_child_at_index(provider.get_child_index("content")).GetSummary();
|
||||
return ''
|
||||
|
||||
class CFStringSynthProvider:
|
||||
def __init__(self,valobj,dict):
|
||||
self.valobj = valobj;
|
||||
self.update()
|
||||
|
||||
# children other than "content" are for debugging only and must not be used in production code
|
||||
def num_children(self):
|
||||
if self.invalid:
|
||||
return 0;
|
||||
return 6;
|
||||
|
||||
def read_unicode(self, pointer):
|
||||
process = self.valobj.GetTarget().GetProcess()
|
||||
error = lldb.SBError()
|
||||
pystr = u''
|
||||
# cannot do the read at once because the length value has
|
||||
# a weird encoding. better play it safe here
|
||||
while True:
|
||||
content = process.ReadMemory(pointer, 2, error)
|
||||
new_bytes = bytearray(content)
|
||||
b0 = new_bytes[0]
|
||||
b1 = new_bytes[1]
|
||||
pointer = pointer + 2
|
||||
if b0 == 0 and b1 == 0:
|
||||
break
|
||||
# rearrange bytes depending on endianness
|
||||
# (do we really need this or is Cocoa going to
|
||||
# use Windows-compatible little-endian even
|
||||
# if the target is big endian?)
|
||||
if self.is_little:
|
||||
value = b1 * 256 + b0
|
||||
else:
|
||||
value = b0 * 256 + b1
|
||||
pystr = pystr + unichr(value)
|
||||
return pystr
|
||||
|
||||
# handle the special case strings
|
||||
# only use the custom code for the tested LP64 case
|
||||
def handle_special(self):
|
||||
if self.lp64 == False:
|
||||
# for 32bit targets, use safe ObjC code
|
||||
return self.handle_unicode_string_safe()
|
||||
offset = 12
|
||||
pointer = self.valobj.GetValueAsUnsigned(0) + offset
|
||||
pystr = self.read_unicode(pointer)
|
||||
return self.valobj.CreateValueFromExpression("content",
|
||||
"(char*)\"" + pystr.encode('utf-8') + "\"")
|
||||
|
||||
# last resort call, use ObjC code to read; the final aim is to
|
||||
# be able to strip this call away entirely and only do the read
|
||||
# ourselves
|
||||
def handle_unicode_string_safe(self):
|
||||
return self.valobj.CreateValueFromExpression("content",
|
||||
"(char*)\"" + self.valobj.GetObjectDescription() + "\"");
|
||||
|
||||
def handle_unicode_string(self):
|
||||
# step 1: find offset
|
||||
if self.inline:
|
||||
pointer = self.valobj.GetValueAsUnsigned(0) + self.size_of_cfruntime_base();
|
||||
if self.explicit == False:
|
||||
# untested, use the safe code path
|
||||
return self.handle_unicode_string_safe();
|
||||
else:
|
||||
# not sure why 8 bytes are skipped here
|
||||
# (lldb) mem read -c 50 0x00000001001154f0
|
||||
# 0x1001154f0: 98 1a 85 71 ff 7f 00 00 90 07 00 00 01 00 00 00 ...q?...........
|
||||
# 0x100115500: 03 00 00 00 00 00 00 00 *c3 03 78 00 78 00 00 00 ........?.x.x...
|
||||
# 0x100115510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
# 0x100115520: 00 00 ..
|
||||
# content begins at * (i.e. 8 bytes into variants, skipping void* buffer in
|
||||
# __notInlineImmutable1 entirely, while the length byte is correctly located
|
||||
# for an inline string)
|
||||
pointer = pointer + 8;
|
||||
else:
|
||||
pointer = self.valobj.GetValueAsUnsigned(0) + self.size_of_cfruntime_base();
|
||||
# read 8 bytes here and make an address out of them
|
||||
vopointer = self.valobj.CreateChildAtOffset("dummy",
|
||||
pointer,self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType());
|
||||
pointer = vopointer.GetValueAsUnsigned(0)
|
||||
# step 2: read Unicode data at pointer
|
||||
pystr = self.read_unicode(pointer)
|
||||
# step 3: return it
|
||||
return self.valobj.CreateValueFromExpression("content",
|
||||
"(char*)\"" + pystr.encode('utf-8') + "\"")
|
||||
|
||||
# we read at "the right place" into the __CFString object instead of running code
|
||||
# we are replicating the functionality of __CFStrContents in CFString.c here
|
||||
def handle_UTF8_inline(self):
|
||||
offset = int(self.valobj.GetValue(), 0) + self.size_of_cfruntime_base();
|
||||
if self.explicit == False:
|
||||
offset = offset + 1;
|
||||
return self.valobj.CreateValueFromAddress("content",
|
||||
offset, self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar)).AddressOf();
|
||||
|
||||
def handle_UTF8_not_inline(self):
|
||||
offset = self.size_of_cfruntime_base();
|
||||
return self.valobj.CreateChildAtOffset("content",
|
||||
offset,self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType());
|
||||
|
||||
def get_child_at_index(self,index):
|
||||
if index == 0:
|
||||
return self.valobj.CreateValueFromExpression("mutable",
|
||||
str(int(self.mutable)));
|
||||
if index == 1:
|
||||
return self.valobj.CreateValueFromExpression("inline",
|
||||
str(int(self.inline)));
|
||||
if index == 2:
|
||||
return self.valobj.CreateValueFromExpression("explicit",
|
||||
str(int(self.explicit)));
|
||||
if index == 3:
|
||||
return self.valobj.CreateValueFromExpression("unicode",
|
||||
str(int(self.unicode)));
|
||||
if index == 4:
|
||||
return self.valobj.CreateValueFromExpression("special",
|
||||
str(int(self.special)));
|
||||
if index == 5:
|
||||
if self.unicode == True:
|
||||
return self.handle_unicode_string();
|
||||
elif self.special == True:
|
||||
return self.handle_special();
|
||||
elif self.inline == True:
|
||||
return self.handle_UTF8_inline();
|
||||
else:
|
||||
return self.handle_UTF8_not_inline();
|
||||
|
||||
def get_child_index(self,name):
|
||||
if name == "content":
|
||||
return self.num_children() - 1;
|
||||
if name == "mutable":
|
||||
return 0;
|
||||
if name == "inline":
|
||||
return 1;
|
||||
if name == "explicit":
|
||||
return 2;
|
||||
if name == "unicode":
|
||||
return 3;
|
||||
if name == "special":
|
||||
return 4;
|
||||
|
||||
def is_64bit(self):
|
||||
return self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8
|
||||
|
||||
def is_little_endian(self):
|
||||
return self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle
|
||||
|
||||
# CFRuntimeBase is defined as having an additional
|
||||
# 4 bytes (padding?) on LP64 architectures
|
||||
# to get its size we add up sizeof(pointer)+4
|
||||
# and then add 4 more bytes if we are on a 64bit system
|
||||
def size_of_cfruntime_base(self):
|
||||
if self.lp64 == True:
|
||||
return 8+4+4;
|
||||
else:
|
||||
return 4+4;
|
||||
|
||||
# the info bits are part of the CFRuntimeBase structure
|
||||
# to get at them we have to skip a uintptr_t and then get
|
||||
# at the least-significant byte of a 4 byte array. If we are
|
||||
# on big-endian this means going to byte 3, if we are on
|
||||
# little endian (OSX & iOS), this means reading byte 0
|
||||
def offset_of_info_bits(self):
|
||||
if self.lp64 == True:
|
||||
offset = 8;
|
||||
else:
|
||||
offset = 4;
|
||||
if self.is_little == False:
|
||||
offset = offset + 3;
|
||||
return offset;
|
||||
|
||||
def read_info_bits(self):
|
||||
cfinfo = self.valobj.CreateChildAtOffset("cfinfo",
|
||||
self.offset_of_info_bits(),
|
||||
self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar));
|
||||
cfinfo.SetFormat(11)
|
||||
info = cfinfo.GetValue();
|
||||
if info != None:
|
||||
self.invalid = False;
|
||||
return int(info,0);
|
||||
else:
|
||||
self.invalid = True;
|
||||
return None;
|
||||
|
||||
# calculating internal flag bits of the CFString object
|
||||
# this stuff is defined and discussed in CFString.c
|
||||
def is_mutable(self):
|
||||
return (self.info_bits & 1) == 1;
|
||||
|
||||
def is_inline(self):
|
||||
return (self.info_bits & 0x60) == 0;
|
||||
|
||||
# this flag's name is ambiguous, it turns out
|
||||
# we must skip a length byte to get at the data
|
||||
# when this flag is False
|
||||
def has_explicit_length(self):
|
||||
return (self.info_bits & (1 | 4)) != 4;
|
||||
|
||||
# probably a subclass of NSString. obtained this from [str pathExtension]
|
||||
# here info_bits = 0 and Unicode data at the start of the padding word
|
||||
# in the long run using the isa value might be safer as a way to identify this
|
||||
# instead of reading the info_bits
|
||||
def is_special_case(self):
|
||||
return self.info_bits == 0;
|
||||
|
||||
def is_unicode(self):
|
||||
return (self.info_bits & 0x10) == 0x10;
|
||||
|
||||
# preparing ourselves to read into memory
|
||||
# by adjusting architecture-specific info
|
||||
def adjust_for_architecture(self):
|
||||
self.lp64 = self.is_64bit();
|
||||
self.is_little = self.is_little_endian();
|
||||
|
||||
# reading info bits out of the CFString and computing
|
||||
# useful values to get at the real data
|
||||
def compute_flags(self):
|
||||
self.info_bits = self.read_info_bits();
|
||||
if self.info_bits == None:
|
||||
return;
|
||||
self.mutable = self.is_mutable();
|
||||
self.inline = self.is_inline();
|
||||
self.explicit = self.has_explicit_length();
|
||||
self.unicode = self.is_unicode();
|
||||
self.special = self.is_special_case();
|
||||
|
||||
def update(self):
|
||||
self.adjust_for_architecture();
|
||||
self.compute_flags();
|
||||
@@ -1,64 +0,0 @@
|
||||
import re
|
||||
class StdListSynthProvider:
|
||||
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj
|
||||
self.update()
|
||||
|
||||
def num_children(self):
|
||||
next_val = self.next.GetValueAsUnsigned(0)
|
||||
prev_val = self.prev.GetValueAsUnsigned(0)
|
||||
# After a std::list has been initialized, both next and prev will be non-NULL
|
||||
if next_val == 0 or prev_val == 0:
|
||||
return 0
|
||||
if next_val == self.node_address:
|
||||
return 0
|
||||
if next_val == prev_val:
|
||||
return 1
|
||||
size = 2
|
||||
current = self.next
|
||||
while current.GetChildMemberWithName('_M_next').GetValueAsUnsigned(0) != self.node_address:
|
||||
size = size + 1
|
||||
current = current.GetChildMemberWithName('_M_next')
|
||||
return (size - 1)
|
||||
|
||||
def get_child_index(self,name):
|
||||
return int(name.lstrip('[').rstrip(']'))
|
||||
|
||||
def get_child_at_index(self,index):
|
||||
if index >= self.num_children():
|
||||
return None;
|
||||
offset = index
|
||||
current = self.next
|
||||
while offset > 0:
|
||||
current = current.GetChildMemberWithName('_M_next')
|
||||
offset = offset - 1
|
||||
return current.CreateChildAtOffset('['+str(index)+']',2*current.GetType().GetByteSize(),self.data_type)
|
||||
|
||||
def extract_type_name(self,name):
|
||||
self.type_name = name[16:]
|
||||
index = 2
|
||||
count_of_template = 1
|
||||
while index < len(self.type_name):
|
||||
if self.type_name[index] == '<':
|
||||
count_of_template = count_of_template + 1
|
||||
elif self.type_name[index] == '>':
|
||||
count_of_template = count_of_template - 1
|
||||
elif self.type_name[index] == ',' and count_of_template == 1:
|
||||
self.type_name = self.type_name[:index]
|
||||
break
|
||||
index = index + 1
|
||||
self.type_name_nospaces = self.type_name.replace(", ", ",")
|
||||
|
||||
def update(self):
|
||||
impl = self.valobj.GetChildMemberWithName('_M_impl')
|
||||
node = impl.GetChildMemberWithName('_M_node')
|
||||
self.extract_type_name(impl.GetType().GetName())
|
||||
self.node_address = self.valobj.AddressOf().GetValueAsUnsigned(0)
|
||||
self.next = node.GetChildMemberWithName('_M_next')
|
||||
self.prev = node.GetChildMemberWithName('_M_prev')
|
||||
self.data_type = node.GetTarget().FindFirstType(self.type_name)
|
||||
# tries to fight against a difference in formatting type names between gcc and clang
|
||||
if self.data_type.IsValid() == False:
|
||||
self.data_type = node.GetTarget().FindFirstType(self.type_name_nospaces)
|
||||
self.data_size = self.data_type.GetByteSize()
|
||||
@@ -1,112 +0,0 @@
|
||||
import re
|
||||
|
||||
class StdMapSynthProvider:
|
||||
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj;
|
||||
self.update()
|
||||
|
||||
def update(self):
|
||||
self.Mt = self.valobj.GetChildMemberWithName('_M_t')
|
||||
self.Mimpl = self.Mt.GetChildMemberWithName('_M_impl')
|
||||
self.Mheader = self.Mimpl.GetChildMemberWithName('_M_header')
|
||||
# from libstdc++ implementation of _M_root for rbtree
|
||||
self.Mroot = self.Mheader.GetChildMemberWithName('_M_parent')
|
||||
# the stuff into the tree is actually a std::pair<const key, value>
|
||||
# life would be much easier if gcc had a coherent way to print out
|
||||
# template names in debug info
|
||||
self.expand_clang_type_name()
|
||||
self.expand_gcc_type_name()
|
||||
self.data_type = self.Mt.GetTarget().FindFirstType(self.clang_type_name)
|
||||
if self.data_type.IsValid() == False:
|
||||
self.data_type = self.Mt.GetTarget().FindFirstType(self.gcc_type_name)
|
||||
self.data_size = self.data_type.GetByteSize()
|
||||
self.skip_size = self.Mheader.GetType().GetByteSize()
|
||||
|
||||
def expand_clang_type_name(self):
|
||||
type_name = self.Mimpl.GetType().GetName()
|
||||
index = type_name.find("std::pair<")
|
||||
type_name = type_name[index+5:]
|
||||
index = 6
|
||||
template_count = 1
|
||||
while index < len(type_name):
|
||||
if type_name[index] == '<':
|
||||
template_count = template_count + 1
|
||||
elif type_name[index] == '>' and template_count == 1:
|
||||
type_name = type_name[:index+1]
|
||||
break
|
||||
elif type_name[index] == '>':
|
||||
template_count = template_count - 1
|
||||
index = index + 1;
|
||||
self.clang_type_name = type_name
|
||||
|
||||
def expand_gcc_type_name(self):
|
||||
type_name = self.Mt.GetType().GetName()
|
||||
index = type_name.find("std::pair<")
|
||||
type_name = type_name[index+5:]
|
||||
index = 6
|
||||
template_count = 1
|
||||
while index < len(type_name):
|
||||
if type_name[index] == '<':
|
||||
template_count = template_count + 1
|
||||
elif type_name[index] == '>' and template_count == 1:
|
||||
type_name = type_name[:index+1]
|
||||
break
|
||||
elif type_name[index] == '>':
|
||||
template_count = template_count - 1
|
||||
elif type_name[index] == ' ' and template_count == 1 and type_name[index-1] == ',':
|
||||
type_name = type_name[0:index] + type_name[index+1:]
|
||||
index = index - 1
|
||||
index = index + 1;
|
||||
self.gcc_type_name = type_name
|
||||
|
||||
def num_children(self):
|
||||
root_ptr_val = self.node_ptr_value(self.Mroot)
|
||||
if root_ptr_val == 0:
|
||||
return 0;
|
||||
return self.Mimpl.GetChildMemberWithName('_M_node_count').GetValueAsUnsigned(0)
|
||||
|
||||
def get_child_index(self,name):
|
||||
return int(name.lstrip('[').rstrip(']'))
|
||||
|
||||
def get_child_at_index(self,index):
|
||||
if index >= self.num_children():
|
||||
return None;
|
||||
offset = index
|
||||
current = self.left(self.Mheader);
|
||||
while offset > 0:
|
||||
current = self.increment_node(current)
|
||||
offset = offset - 1;
|
||||
# skip all the base stuff and get at the data
|
||||
return current.CreateChildAtOffset('['+str(index)+']',self.skip_size,self.data_type)
|
||||
|
||||
# utility functions
|
||||
def node_ptr_value(self,node):
|
||||
return node.GetValueAsUnsigned(0)
|
||||
|
||||
def right(self,node):
|
||||
return node.GetChildMemberWithName("_M_right");
|
||||
|
||||
def left(self,node):
|
||||
return node.GetChildMemberWithName("_M_left");
|
||||
|
||||
def parent(self,node):
|
||||
return node.GetChildMemberWithName("_M_parent");
|
||||
|
||||
# from libstdc++ implementation of iterator for rbtree
|
||||
def increment_node(self,node):
|
||||
if self.node_ptr_value(self.right(node)) != 0:
|
||||
x = self.right(node);
|
||||
while self.node_ptr_value(self.left(x)) != 0:
|
||||
x = self.left(x);
|
||||
return x;
|
||||
else:
|
||||
x = node;
|
||||
y = self.parent(x)
|
||||
while(self.node_ptr_value(x) == self.node_ptr_value(self.right(y))):
|
||||
x = y;
|
||||
y = self.parent(y);
|
||||
if self.node_ptr_value(self.right(x)) != self.node_ptr_value(y):
|
||||
x = y;
|
||||
return x;
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
class StdVectorSynthProvider:
|
||||
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj;
|
||||
self.update() # initialize this provider
|
||||
|
||||
def num_children(self):
|
||||
start_val = self.start.GetValueAsUnsigned(0) # read _M_start
|
||||
finish_val = self.finish.GetValueAsUnsigned(0) # read _M_finish
|
||||
end_val = self.end.GetValueAsUnsigned(0) # read _M_end_of_storage
|
||||
|
||||
# Before a vector has been constructed, it will contain bad values
|
||||
# so we really need to be careful about the length we return since
|
||||
# unitialized data can cause us to return a huge number. We need
|
||||
# to also check for any of the start, finish or end of storage values
|
||||
# being zero (NULL). If any are, then this vector has not been
|
||||
# initialized yet and we should return zero
|
||||
|
||||
# Make sure nothing is NULL
|
||||
if start_val == 0 or finish_val == 0 or end_val == 0:
|
||||
return 0
|
||||
# Make sure start is less than finish
|
||||
if start_val >= finish_val:
|
||||
return 0
|
||||
# Make sure finish is less than or equal to end of storage
|
||||
if finish_val > end_val:
|
||||
return 0
|
||||
|
||||
# pointer arithmetic: (_M_finish - _M_start) would return the number of
|
||||
# items of type T contained in the vector. because Python has no way to know
|
||||
# that we want to subtract two pointers instead of two integers, we have to divide
|
||||
# by sizeof(T) to be equivalent to the C++ pointer expression
|
||||
num_children = (finish_val-start_val)/self.data_size
|
||||
return num_children
|
||||
|
||||
# we assume we are getting children named [0] thru [N-1]
|
||||
# if for some reason our child name is not in this format,
|
||||
# do not bother to show it, and return an invalid value
|
||||
def get_child_index(self,name):
|
||||
try:
|
||||
return int(name.lstrip('[').rstrip(']'))
|
||||
except:
|
||||
return -1;
|
||||
|
||||
def get_child_at_index(self,index):
|
||||
# LLDB itself should never query for children < 0, but this might come
|
||||
# from someone asking for a nonexisting child and getting -1 as index
|
||||
if index < 0:
|
||||
return None
|
||||
if index >= self.num_children():
|
||||
return None;
|
||||
# *(_M_start + index), or equivalently _M_start[index] is C++ code to
|
||||
# read the index-th item of the vector. in Python we must make an offset
|
||||
# that is index * sizeof(T), and then grab the value at that offset from
|
||||
# _M_start
|
||||
offset = index * self.data_size # index * sizeof(T)
|
||||
return self.start.CreateChildAtOffset('['+str(index)+']',offset,self.data_type) # *(_M_start + index)
|
||||
|
||||
# an std::vector contains an object named _M_impl, which in turn contains
|
||||
# three pointers, _M_start, _M_end and _M_end_of_storage. _M_start points to the
|
||||
# beginning of the data area, _M_finish points to where the current vector elements
|
||||
# finish, and _M_end_of_storage is the end of the currently alloc'ed memory portion
|
||||
# (to allow resizing, a vector may allocate more memory than required)
|
||||
def update(self):
|
||||
impl = self.valobj.GetChildMemberWithName('_M_impl')
|
||||
self.start = impl.GetChildMemberWithName('_M_start')
|
||||
self.finish = impl.GetChildMemberWithName('_M_finish')
|
||||
self.end = impl.GetChildMemberWithName('_M_end_of_storage')
|
||||
self.data_type = self.start.GetType().GetPointeeType() # _M_start is defined as a T*
|
||||
self.data_size = self.data_type.GetByteSize() # sizeof(T)
|
||||
|
||||
@@ -1,272 +0,0 @@
|
||||
import re
|
||||
|
||||
# C++ STL formatters for LLDB
|
||||
# These formatters are based upon the version of the GNU libstdc++
|
||||
# as it ships with Mac OS X 10.6.8 and 10.7.0
|
||||
# You are encouraged to look at the STL implementation for your platform
|
||||
# before relying on these formatters to do the right thing for your setup
|
||||
|
||||
class StdListSynthProvider:
|
||||
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj
|
||||
self.update()
|
||||
|
||||
def num_children(self):
|
||||
try:
|
||||
next_val = self.next.GetValueAsUnsigned(0)
|
||||
prev_val = self.prev.GetValueAsUnsigned(0)
|
||||
# After a std::list has been initialized, both next and prev will be non-NULL
|
||||
if next_val == 0 or prev_val == 0:
|
||||
return 0
|
||||
if next_val == self.node_address:
|
||||
return 0
|
||||
if next_val == prev_val:
|
||||
return 1
|
||||
size = 2
|
||||
current = self.next
|
||||
while current.GetChildMemberWithName('_M_next').GetValueAsUnsigned(0) != self.node_address:
|
||||
size = size + 1
|
||||
current = current.GetChildMemberWithName('_M_next')
|
||||
return (size - 1)
|
||||
except:
|
||||
return 0;
|
||||
|
||||
def get_child_index(self,name):
|
||||
try:
|
||||
return int(name.lstrip('[').rstrip(']'))
|
||||
except:
|
||||
return -1
|
||||
|
||||
def get_child_at_index(self,index):
|
||||
if index < 0:
|
||||
return None;
|
||||
if index >= self.num_children():
|
||||
return None;
|
||||
try:
|
||||
offset = index
|
||||
current = self.next
|
||||
while offset > 0:
|
||||
current = current.GetChildMemberWithName('_M_next')
|
||||
offset = offset - 1
|
||||
return current.CreateChildAtOffset('['+str(index)+']',2*current.GetType().GetByteSize(),self.data_type)
|
||||
except:
|
||||
return None
|
||||
|
||||
def extract_type_name(self,name):
|
||||
self.type_name = name[16:]
|
||||
index = 2
|
||||
count_of_template = 1
|
||||
while index < len(self.type_name):
|
||||
if self.type_name[index] == '<':
|
||||
count_of_template = count_of_template + 1
|
||||
elif self.type_name[index] == '>':
|
||||
count_of_template = count_of_template - 1
|
||||
elif self.type_name[index] == ',' and count_of_template == 1:
|
||||
self.type_name = self.type_name[:index]
|
||||
break
|
||||
index = index + 1
|
||||
self.type_name_nospaces = self.type_name.replace(", ", ",")
|
||||
|
||||
def update(self):
|
||||
try:
|
||||
impl = self.valobj.GetChildMemberWithName('_M_impl')
|
||||
node = impl.GetChildMemberWithName('_M_node')
|
||||
self.extract_type_name(impl.GetType().GetName())
|
||||
self.node_address = self.valobj.AddressOf().GetValueAsUnsigned(0)
|
||||
self.next = node.GetChildMemberWithName('_M_next')
|
||||
self.prev = node.GetChildMemberWithName('_M_prev')
|
||||
self.data_type = node.GetTarget().FindFirstType(self.type_name)
|
||||
# tries to fight against a difference in formatting type names between gcc and clang
|
||||
if self.data_type.IsValid() == False:
|
||||
self.data_type = node.GetTarget().FindFirstType(self.type_name_nospaces)
|
||||
self.data_size = self.data_type.GetByteSize()
|
||||
except:
|
||||
pass
|
||||
|
||||
class StdVectorSynthProvider:
|
||||
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj;
|
||||
self.update()
|
||||
|
||||
def num_children(self):
|
||||
try:
|
||||
start_val = self.start.GetValueAsUnsigned(0)
|
||||
finish_val = self.finish.GetValueAsUnsigned(0)
|
||||
end_val = self.end.GetValueAsUnsigned(0)
|
||||
# Before a vector has been constructed, it will contain bad values
|
||||
# so we really need to be careful about the length we return since
|
||||
# unitialized data can cause us to return a huge number. We need
|
||||
# to also check for any of the start, finish or end of storage values
|
||||
# being zero (NULL). If any are, then this vector has not been
|
||||
# initialized yet and we should return zero
|
||||
|
||||
# Make sure nothing is NULL
|
||||
if start_val == 0 or finish_val == 0 or end_val == 0:
|
||||
return 0
|
||||
# Make sure start is less than finish
|
||||
if start_val >= finish_val:
|
||||
return 0
|
||||
# Make sure finish is less than or equal to end of storage
|
||||
if finish_val > end_val:
|
||||
return 0
|
||||
|
||||
num_children = (finish_val-start_val)/self.data_size
|
||||
return num_children
|
||||
except:
|
||||
return 0;
|
||||
|
||||
def get_child_index(self,name):
|
||||
try:
|
||||
return int(name.lstrip('[').rstrip(']'))
|
||||
except:
|
||||
return -1
|
||||
|
||||
def get_child_at_index(self,index):
|
||||
if index < 0:
|
||||
return None;
|
||||
if index >= self.num_children():
|
||||
return None;
|
||||
try:
|
||||
offset = index * self.data_size
|
||||
return self.start.CreateChildAtOffset('['+str(index)+']',offset,self.data_type)
|
||||
except:
|
||||
return None
|
||||
|
||||
def update(self):
|
||||
try:
|
||||
impl = self.valobj.GetChildMemberWithName('_M_impl')
|
||||
self.start = impl.GetChildMemberWithName('_M_start')
|
||||
self.finish = impl.GetChildMemberWithName('_M_finish')
|
||||
self.end = impl.GetChildMemberWithName('_M_end_of_storage')
|
||||
self.data_type = self.start.GetType().GetPointeeType()
|
||||
self.data_size = self.data_type.GetByteSize()
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
class StdMapSynthProvider:
|
||||
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj;
|
||||
self.update()
|
||||
|
||||
def update(self):
|
||||
try:
|
||||
self.Mt = self.valobj.GetChildMemberWithName('_M_t')
|
||||
self.Mimpl = self.Mt.GetChildMemberWithName('_M_impl')
|
||||
self.Mheader = self.Mimpl.GetChildMemberWithName('_M_header')
|
||||
# from libstdc++ implementation of _M_root for rbtree
|
||||
self.Mroot = self.Mheader.GetChildMemberWithName('_M_parent')
|
||||
# the stuff into the tree is actually a std::pair<const key, value>
|
||||
# life would be much easier if gcc had a coherent way to print out
|
||||
# template names in debug info
|
||||
self.expand_clang_type_name()
|
||||
self.expand_gcc_type_name()
|
||||
self.data_type = self.Mt.GetTarget().FindFirstType(self.clang_type_name)
|
||||
if self.data_type.IsValid() == False:
|
||||
self.data_type = self.Mt.GetTarget().FindFirstType(self.gcc_type_name)
|
||||
self.data_size = self.data_type.GetByteSize()
|
||||
self.skip_size = self.Mheader.GetType().GetByteSize()
|
||||
except:
|
||||
pass
|
||||
|
||||
def expand_clang_type_name(self):
|
||||
type_name = self.Mimpl.GetType().GetName()
|
||||
index = type_name.find("std::pair<")
|
||||
type_name = type_name[index+5:]
|
||||
index = 6
|
||||
template_count = 1
|
||||
while index < len(type_name):
|
||||
if type_name[index] == '<':
|
||||
template_count = template_count + 1
|
||||
elif type_name[index] == '>' and template_count == 1:
|
||||
type_name = type_name[:index+1]
|
||||
break
|
||||
elif type_name[index] == '>':
|
||||
template_count = template_count - 1
|
||||
index = index + 1;
|
||||
self.clang_type_name = type_name
|
||||
|
||||
def expand_gcc_type_name(self):
|
||||
type_name = self.Mt.GetType().GetName()
|
||||
index = type_name.find("std::pair<")
|
||||
type_name = type_name[index+5:]
|
||||
index = 6
|
||||
template_count = 1
|
||||
while index < len(type_name):
|
||||
if type_name[index] == '<':
|
||||
template_count = template_count + 1
|
||||
elif type_name[index] == '>' and template_count == 1:
|
||||
type_name = type_name[:index+1]
|
||||
break
|
||||
elif type_name[index] == '>':
|
||||
template_count = template_count - 1
|
||||
elif type_name[index] == ' ' and template_count == 1 and type_name[index-1] == ',':
|
||||
type_name = type_name[0:index] + type_name[index+1:]
|
||||
index = index - 1
|
||||
index = index + 1;
|
||||
self.gcc_type_name = type_name
|
||||
|
||||
def num_children(self):
|
||||
try:
|
||||
root_ptr_val = self.node_ptr_value(self.Mroot)
|
||||
if root_ptr_val == 0:
|
||||
return 0;
|
||||
return self.Mimpl.GetChildMemberWithName('_M_node_count').GetValueAsUnsigned(0)
|
||||
except:
|
||||
return 0;
|
||||
|
||||
def get_child_index(self,name):
|
||||
try:
|
||||
return int(name.lstrip('[').rstrip(']'))
|
||||
except:
|
||||
return -1
|
||||
|
||||
def get_child_at_index(self,index):
|
||||
if index < 0:
|
||||
return None
|
||||
if index >= self.num_children():
|
||||
return None;
|
||||
try:
|
||||
offset = index
|
||||
current = self.left(self.Mheader);
|
||||
while offset > 0:
|
||||
current = self.increment_node(current)
|
||||
offset = offset - 1;
|
||||
# skip all the base stuff and get at the data
|
||||
return current.CreateChildAtOffset('['+str(index)+']',self.skip_size,self.data_type)
|
||||
except:
|
||||
return None
|
||||
|
||||
# utility functions
|
||||
def node_ptr_value(self,node):
|
||||
return node.GetValueAsUnsigned(0)
|
||||
|
||||
def right(self,node):
|
||||
return node.GetChildMemberWithName("_M_right");
|
||||
|
||||
def left(self,node):
|
||||
return node.GetChildMemberWithName("_M_left");
|
||||
|
||||
def parent(self,node):
|
||||
return node.GetChildMemberWithName("_M_parent");
|
||||
|
||||
# from libstdc++ implementation of iterator for rbtree
|
||||
def increment_node(self,node):
|
||||
if self.node_ptr_value(self.right(node)) != 0:
|
||||
x = self.right(node);
|
||||
while self.node_ptr_value(self.left(x)) != 0:
|
||||
x = self.left(x);
|
||||
return x;
|
||||
else:
|
||||
x = node;
|
||||
y = self.parent(x)
|
||||
while(self.node_ptr_value(x) == self.node_ptr_value(self.right(y))):
|
||||
x = y;
|
||||
y = self.parent(y);
|
||||
if self.node_ptr_value(self.right(x)) != self.node_ptr_value(y):
|
||||
x = y;
|
||||
return x;
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
"""
|
||||
Objective-C runtime wrapper - Replicates the behavior of AppleObjCRuntimeV2.cpp in Python code
|
||||
for the benefit of synthetic children providers and Python summaries
|
||||
|
||||
part of The LLVM Compiler Infrastructure
|
||||
This file is distributed under the University of Illinois Open Source
|
||||
License. See LICENSE.TXT for details.
|
||||
"""
|
||||
import lldb
|
||||
|
||||
class ObjCRuntime:
|
||||
|
||||
def __init__(self,valobj = None):
|
||||
self.valobj = valobj;
|
||||
self.adjust_for_architecture()
|
||||
|
||||
def adjust_for_architecture(self):
|
||||
self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
|
||||
self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
|
||||
self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
|
||||
self.addr_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
|
||||
self.addr_ptr_type = self.addr_type.GetPointerType()
|
||||
|
||||
def is_tagged(self):
|
||||
if valobj is None:
|
||||
return None
|
||||
ptr_value = self.valobj.GetPointerValue()
|
||||
if (ptr_value % 2) == 1:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def read_ascii(self, pointer):
|
||||
process = self.valobj.GetTarget().GetProcess()
|
||||
error = lldb.SBError()
|
||||
pystr = ''
|
||||
# cannot do the read at once because there is no length byte
|
||||
while True:
|
||||
content = process.ReadMemory(pointer, 1, error)
|
||||
new_bytes = bytearray(content)
|
||||
b0 = new_bytes[0]
|
||||
pointer = pointer + 1
|
||||
if b0 == 0:
|
||||
break
|
||||
pystr = pystr + chr(b0)
|
||||
return pystr
|
||||
|
||||
def read_isa(self):
|
||||
# read ISA pointer
|
||||
isa_pointer = self.valobj.CreateChildAtOffset("cfisa",
|
||||
0,
|
||||
self.addr_ptr_type)
|
||||
if isa_pointer == None or isa_pointer.IsValid() == False:
|
||||
return None;
|
||||
if isa_pointer.GetValue() == None:
|
||||
return None;
|
||||
isa = int(isa_pointer.GetValue(), 0)
|
||||
if isa == 0 or isa == None:
|
||||
return None;
|
||||
return isa
|
||||
|
||||
|
||||
def get_parent_class(self, isa = None):
|
||||
if isa is None:
|
||||
isa = self.read_isa()
|
||||
# read superclass pointer
|
||||
rw_pointer = isa + self.pointer_size
|
||||
rw_object = self.valobj.CreateValueFromAddress("parent_isa",
|
||||
rw_pointer,
|
||||
self.addr_type)
|
||||
if rw_object == None or rw_object.IsValid() == False:
|
||||
return None;
|
||||
if rw_object.GetValue() == None:
|
||||
return None;
|
||||
rw = int(rw_object.GetValue(), 0)
|
||||
if rw == 0 or rw == None:
|
||||
return None;
|
||||
return rw
|
||||
|
||||
def get_class_name(self, isa = None):
|
||||
if isa is None:
|
||||
isa = self.read_isa()
|
||||
# read rw pointer
|
||||
rw_pointer = isa + 4 * self.pointer_size
|
||||
rw_object = self.valobj.CreateValueFromAddress("rw",
|
||||
rw_pointer,
|
||||
self.addr_type)
|
||||
if rw_object == None or rw_object.IsValid() == False:
|
||||
return None;
|
||||
if rw_object.GetValue() == None:
|
||||
return None;
|
||||
rw = int(rw_object.GetValue(), 0)
|
||||
if rw == 0 or rw == None:
|
||||
return None;
|
||||
|
||||
# read data pointer
|
||||
data_pointer = rw + 8
|
||||
data_object = self.valobj.CreateValueFromAddress("data",
|
||||
data_pointer,
|
||||
self.addr_type)
|
||||
if data_object == None or data_object.IsValid() == False:
|
||||
return None;
|
||||
if data_object.GetValue() == None:
|
||||
return None;
|
||||
data = int(data_object.GetValue(), 0)
|
||||
if data == 0 or data == None:
|
||||
return None;
|
||||
|
||||
# read ro pointer
|
||||
ro_pointer = data + 12 + self.pointer_size
|
||||
if self.lp64:
|
||||
ro_pointer += 4
|
||||
ro_object = self.valobj.CreateValueFromAddress("ro",
|
||||
ro_pointer,
|
||||
self.addr_type)
|
||||
if ro_object == None or ro_object.IsValid() == False:
|
||||
return None;
|
||||
if ro_object.GetValue() == None:
|
||||
return None;
|
||||
name_pointer = int(ro_object.GetValue(), 0)
|
||||
if name_pointer == 0 or name_pointer == None:
|
||||
return None;
|
||||
|
||||
# now read the actual name and compare it to known stuff
|
||||
name_string = self.read_ascii(name_pointer)
|
||||
if (name_string.startswith("NSKVONotify")):
|
||||
return self.get_class_name(self.get_parent_class())
|
||||
return name_string
|
||||
@@ -1,6 +0,0 @@
|
||||
sys.stderr = open("/tmp/lldbtest-stderr", "w")
|
||||
sys.stdout = open("/tmp/lldbtest-stdout", "w")
|
||||
compilers = ["gcc", "llvm-gcc"]
|
||||
archs = ["x86_64", "i386"]
|
||||
split_stderr = True # This will split the stderr into configuration-specific file
|
||||
split_stdout = True # This will split the stdout into configuration-specific file
|
||||
@@ -1,19 +0,0 @@
|
||||
# Example config file for running the test suite for both 64 and 32-bit
|
||||
# architectures.
|
||||
#
|
||||
# I use the following command to invoke the test driver:
|
||||
#
|
||||
# /Volumes/data/lldb/svn/trunk/test $ ./dotest.py -r /Volumes/data/lldb-test/archs -s session -c ../examples/test/.lldbtest-config2 -v -w . 2> ~/Developer/Log/lldbtest.log
|
||||
#
|
||||
# The '-r' option tells the driver to relocate the test execution to
|
||||
# /Volumes/data/lldb-test/archs which must not exist before the run.
|
||||
#
|
||||
# Test failures/errors will be recorded into the 'session' directory due to the
|
||||
# '-s' option, e.g., /Volumes/data/lldb-test/archs.arch=i386/test/session could
|
||||
# contain the following three session info files:
|
||||
#
|
||||
# -rw-r--r-- 1 johnny admin 1737 Oct 25 13:25 TestArrayTypes.ArrayTypesTestCase.test_with_dwarf_and_run_command.log
|
||||
# -rw-r--r-- 1 johnny admin 1733 Oct 25 13:25 TestClassTypes.ClassTypesTestCase.test_with_dwarf_and_run_command.log
|
||||
# -rw-r--r-- 1 johnny admin 4677 Oct 25 13:26 TestObjCMethods.FoundationTestCase.test_data_type_and_expr_with_dsym.log
|
||||
|
||||
archs = ["x86_64", "i386"]
|
||||
@@ -1,39 +0,0 @@
|
||||
----------------------------------------------------------------------
|
||||
Collected 1 test
|
||||
|
||||
|
||||
Configuration: arch=x86_64 compiler=gcc
|
||||
test_persistent_variables (TestPersistentVariables.PersistentVariablesTestCase)
|
||||
Test that lldb persistent variables works correctly. ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in 1.397s
|
||||
|
||||
OK
|
||||
|
||||
Configuration: arch=x86_64 compiler=llvm-gcc
|
||||
test_persistent_variables (TestPersistentVariables.PersistentVariablesTestCase)
|
||||
Test that lldb persistent variables works correctly. ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in 1.282s
|
||||
|
||||
OK
|
||||
|
||||
Configuration: arch=i386 compiler=gcc
|
||||
test_persistent_variables (TestPersistentVariables.PersistentVariablesTestCase)
|
||||
Test that lldb persistent variables works correctly. ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in 1.297s
|
||||
|
||||
OK
|
||||
|
||||
Configuration: arch=i386 compiler=llvm-gcc
|
||||
test_persistent_variables (TestPersistentVariables.PersistentVariablesTestCase)
|
||||
Test that lldb persistent variables works correctly. ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in 1.269s
|
||||
|
||||
OK
|
||||
@@ -1,10 +0,0 @@
|
||||
# This is an example of using the "-c" option to source a config file to
|
||||
# reassign the system stderr and stdout and to exercise different combinations
|
||||
# of architectures and compilers.
|
||||
#
|
||||
# The config file is checked in as .lldbtest-config and the redirected stderr
|
||||
# and stdout are checked in as lldbtest-stderr and lldbtest-stdout, all in the
|
||||
# the same directory as this file.
|
||||
|
||||
[15:36:32] johnny:/Volumes/data/lldb/svn/trunk/test $ ./dotest.py -v -c ~/.lldbtest-config persistent_variables
|
||||
[15:40:55] johnny:/Volumes/data/lldb/svn/trunk/test $
|
||||
@@ -1,13 +0,0 @@
|
||||
##===- include/Makefile ------------------------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
LLDB_LEVEL := ..
|
||||
DIRS := lldb
|
||||
|
||||
include $(LLDB_LEVEL)/Makefile
|
||||
@@ -1,52 +0,0 @@
|
||||
//===-- LLDB.h --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_LLDB_h_
|
||||
#define LLDB_LLDB_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBAddress.h"
|
||||
#include "lldb/API/SBBlock.h"
|
||||
#include "lldb/API/SBBreakpoint.h"
|
||||
#include "lldb/API/SBBreakpointLocation.h"
|
||||
#include "lldb/API/SBBroadcaster.h"
|
||||
#include "lldb/API/SBCommandInterpreter.h"
|
||||
#include "lldb/API/SBCommandReturnObject.h"
|
||||
#include "lldb/API/SBCommunication.h"
|
||||
#include "lldb/API/SBCompileUnit.h"
|
||||
#include "lldb/API/SBData.h"
|
||||
#include "lldb/API/SBDebugger.h"
|
||||
#include "lldb/API/SBError.h"
|
||||
#include "lldb/API/SBEvent.h"
|
||||
#include "lldb/API/SBFileSpec.h"
|
||||
#include "lldb/API/SBFrame.h"
|
||||
#include "lldb/API/SBFunction.h"
|
||||
#include "lldb/API/SBHostOS.h"
|
||||
#include "lldb/API/SBInputReader.h"
|
||||
#include "lldb/API/SBInstruction.h"
|
||||
#include "lldb/API/SBInstructionList.h"
|
||||
#include "lldb/API/SBLineEntry.h"
|
||||
#include "lldb/API/SBListener.h"
|
||||
#include "lldb/API/SBModule.h"
|
||||
#include "lldb/API/SBProcess.h"
|
||||
#include "lldb/API/SBSourceManager.h"
|
||||
#include "lldb/API/SBStringList.h"
|
||||
#include "lldb/API/SBSymbol.h"
|
||||
#include "lldb/API/SBSymbolContext.h"
|
||||
#include "lldb/API/SBTarget.h"
|
||||
#include "lldb/API/SBThread.h"
|
||||
#include "lldb/API/SBType.h"
|
||||
#include "lldb/API/SBValue.h"
|
||||
#include "lldb/API/SBValueList.h"
|
||||
|
||||
#endif // LLDB_LLDB_h_
|
||||
@@ -1,147 +0,0 @@
|
||||
//===-- SBAddress.h ---------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBAddress_h_
|
||||
#define LLDB_SBAddress_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBModule.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBAddress
|
||||
{
|
||||
public:
|
||||
|
||||
SBAddress ();
|
||||
|
||||
SBAddress (const lldb::SBAddress &rhs);
|
||||
|
||||
// Create an address by resolving a load address using the supplied target
|
||||
SBAddress (lldb::addr_t load_addr, lldb::SBTarget &target);
|
||||
|
||||
~SBAddress ();
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBAddress &
|
||||
operator = (const lldb::SBAddress &rhs);
|
||||
#endif
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
addr_t
|
||||
GetFileAddress () const;
|
||||
|
||||
addr_t
|
||||
GetLoadAddress (const lldb::SBTarget &target) const;
|
||||
|
||||
void
|
||||
SetLoadAddress (lldb::addr_t load_addr,
|
||||
lldb::SBTarget &target);
|
||||
bool
|
||||
OffsetAddress (addr_t offset);
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
// The following queries can lookup symbol information for a given address.
|
||||
// An address might refer to code or data from an existing module, or it
|
||||
// might refer to something on the stack or heap. The following functions
|
||||
// will only return valid values if the address has been resolved to a code
|
||||
// or data address using "void SBAddress::SetLoadAddress(...)" or
|
||||
// "lldb::SBAddress SBTarget::ResolveLoadAddress (...)".
|
||||
lldb::SBSymbolContext
|
||||
GetSymbolContext (uint32_t resolve_scope);
|
||||
|
||||
|
||||
// The following functions grab individual objects for a given address and
|
||||
// are less efficient if you want more than one symbol related objects.
|
||||
// Use one of the following when you want multiple debug symbol related
|
||||
// objects for an address:
|
||||
// lldb::SBSymbolContext SBAddress::GetSymbolContext (uint32_t resolve_scope);
|
||||
// lldb::SBSymbolContext SBTarget::ResolveSymbolContextForAddress (const SBAddress &addr, uint32_t resolve_scope);
|
||||
// One or more bits from the SymbolContextItem enumerations can be logically
|
||||
// OR'ed together to more efficiently retrieve multiple symbol objects.
|
||||
|
||||
lldb::SBSection
|
||||
GetSection ();
|
||||
|
||||
lldb::SBModule
|
||||
GetModule ();
|
||||
|
||||
lldb::SBCompileUnit
|
||||
GetCompileUnit ();
|
||||
|
||||
lldb::SBFunction
|
||||
GetFunction ();
|
||||
|
||||
lldb::SBBlock
|
||||
GetBlock ();
|
||||
|
||||
lldb::SBSymbol
|
||||
GetSymbol ();
|
||||
|
||||
lldb::SBLineEntry
|
||||
GetLineEntry ();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
friend class SBBlock;
|
||||
friend class SBBreakpointLocation;
|
||||
friend class SBFrame;
|
||||
friend class SBFunction;
|
||||
friend class SBLineEntry;
|
||||
friend class SBInstruction;
|
||||
friend class SBModule;
|
||||
friend class SBSection;
|
||||
friend class SBSymbol;
|
||||
friend class SBSymbolContext;
|
||||
friend class SBTarget;
|
||||
friend class SBThread;
|
||||
friend class SBValue;
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
lldb_private::Address *
|
||||
operator->();
|
||||
|
||||
const lldb_private::Address *
|
||||
operator->() const;
|
||||
|
||||
lldb_private::Address *
|
||||
get ();
|
||||
|
||||
lldb_private::Address &
|
||||
ref();
|
||||
|
||||
const lldb_private::Address &
|
||||
ref() const;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
SBAddress (const lldb_private::Address *lldb_object_ptr);
|
||||
|
||||
void
|
||||
SetAddress (const lldb_private::Address *lldb_object_ptr);
|
||||
|
||||
private:
|
||||
|
||||
std::auto_ptr<lldb_private::AddressImpl> m_opaque_ap;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBAddress_h_
|
||||
@@ -1,113 +0,0 @@
|
||||
//===-- SBBlock.h -----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBBlock_h_
|
||||
#define LLDB_SBBlock_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBBlock
|
||||
{
|
||||
public:
|
||||
|
||||
SBBlock ();
|
||||
|
||||
SBBlock (const lldb::SBBlock &rhs);
|
||||
|
||||
~SBBlock ();
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBBlock &
|
||||
operator = (const lldb::SBBlock &rhs);
|
||||
#endif
|
||||
|
||||
bool
|
||||
IsInlined () const;
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
const char *
|
||||
GetInlinedName () const;
|
||||
|
||||
lldb::SBFileSpec
|
||||
GetInlinedCallSiteFile () const;
|
||||
|
||||
uint32_t
|
||||
GetInlinedCallSiteLine () const;
|
||||
|
||||
uint32_t
|
||||
GetInlinedCallSiteColumn () const;
|
||||
|
||||
lldb::SBBlock
|
||||
GetParent ();
|
||||
|
||||
lldb::SBBlock
|
||||
GetSibling ();
|
||||
|
||||
lldb::SBBlock
|
||||
GetFirstChild ();
|
||||
|
||||
uint32_t
|
||||
GetNumRanges ();
|
||||
|
||||
lldb::SBAddress
|
||||
GetRangeStartAddress (uint32_t idx);
|
||||
|
||||
lldb::SBAddress
|
||||
GetRangeEndAddress (uint32_t idx);
|
||||
|
||||
uint32_t
|
||||
GetRangeIndexForBlockAddress (lldb::SBAddress block_addr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the inlined block that contains this block.
|
||||
///
|
||||
/// @return
|
||||
/// If this block is inlined, it will return this block, else
|
||||
/// parent blocks will be searched to see if any contain this
|
||||
/// block and are themselves inlined. An invalid SBBlock will
|
||||
/// be returned if this block nor any parent blocks are inlined
|
||||
/// function blocks.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBBlock
|
||||
GetContainingInlinedBlock ();
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
private:
|
||||
friend class SBAddress;
|
||||
friend class SBFrame;
|
||||
friend class SBSymbolContext;
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
lldb_private::Block *
|
||||
get ();
|
||||
|
||||
void
|
||||
reset (lldb_private::Block *lldb_object_ptr);
|
||||
|
||||
SBBlock (lldb_private::Block *lldb_object_ptr);
|
||||
|
||||
void
|
||||
AppendVariables (bool can_create, bool get_parent_variables, lldb_private::VariableList *var_list);
|
||||
|
||||
#endif
|
||||
|
||||
lldb_private::Block *m_opaque_ptr;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBBlock_h_
|
||||
@@ -1,163 +0,0 @@
|
||||
//===-- SBBreakpoint.h ------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBBreakpoint_h_
|
||||
#define LLDB_SBBreakpoint_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBBreakpoint
|
||||
{
|
||||
public:
|
||||
|
||||
typedef bool (*BreakpointHitCallback) (void *baton,
|
||||
SBProcess &process,
|
||||
SBThread &thread,
|
||||
lldb::SBBreakpointLocation &location);
|
||||
|
||||
SBBreakpoint ();
|
||||
|
||||
SBBreakpoint (const lldb::SBBreakpoint& rhs);
|
||||
|
||||
~SBBreakpoint();
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBBreakpoint &
|
||||
operator = (const lldb::SBBreakpoint& rhs);
|
||||
|
||||
// Tests to see if the opaque breakpoint object in this object matches the
|
||||
// opaque breakpoint object in "rhs".
|
||||
bool
|
||||
operator == (const lldb::SBBreakpoint& rhs);
|
||||
|
||||
#endif
|
||||
|
||||
break_id_t
|
||||
GetID () const;
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
void
|
||||
ClearAllBreakpointSites ();
|
||||
|
||||
lldb::SBBreakpointLocation
|
||||
FindLocationByAddress (lldb::addr_t vm_addr);
|
||||
|
||||
lldb::break_id_t
|
||||
FindLocationIDByAddress (lldb::addr_t vm_addr);
|
||||
|
||||
lldb::SBBreakpointLocation
|
||||
FindLocationByID (lldb::break_id_t bp_loc_id);
|
||||
|
||||
lldb::SBBreakpointLocation
|
||||
GetLocationAtIndex (uint32_t index);
|
||||
|
||||
void
|
||||
SetEnabled (bool enable);
|
||||
|
||||
bool
|
||||
IsEnabled ();
|
||||
|
||||
uint32_t
|
||||
GetHitCount () const;
|
||||
|
||||
void
|
||||
SetIgnoreCount (uint32_t count);
|
||||
|
||||
uint32_t
|
||||
GetIgnoreCount () const;
|
||||
|
||||
void
|
||||
SetCondition (const char *condition);
|
||||
|
||||
const char *
|
||||
GetCondition ();
|
||||
|
||||
void
|
||||
SetThreadID (lldb::tid_t sb_thread_id);
|
||||
|
||||
lldb::tid_t
|
||||
GetThreadID ();
|
||||
|
||||
void
|
||||
SetThreadIndex (uint32_t index);
|
||||
|
||||
uint32_t
|
||||
GetThreadIndex() const;
|
||||
|
||||
void
|
||||
SetThreadName (const char *thread_name);
|
||||
|
||||
const char *
|
||||
GetThreadName () const;
|
||||
|
||||
void
|
||||
SetQueueName (const char *queue_name);
|
||||
|
||||
const char *
|
||||
GetQueueName () const;
|
||||
|
||||
void
|
||||
SetCallback (BreakpointHitCallback callback, void *baton);
|
||||
|
||||
size_t
|
||||
GetNumResolvedLocations() const;
|
||||
|
||||
size_t
|
||||
GetNumLocations() const;
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
static lldb::BreakpointEventType
|
||||
GetBreakpointEventTypeFromEvent (const lldb::SBEvent& event);
|
||||
|
||||
static lldb::SBBreakpoint
|
||||
GetBreakpointFromEvent (const lldb::SBEvent& event);
|
||||
|
||||
static lldb::SBBreakpointLocation
|
||||
GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx);
|
||||
|
||||
private:
|
||||
friend class SBBreakpointLocation;
|
||||
friend class SBTarget;
|
||||
|
||||
SBBreakpoint (const lldb::BreakpointSP &bp_sp);
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
lldb_private::Breakpoint *
|
||||
operator->() const;
|
||||
|
||||
lldb_private::Breakpoint *
|
||||
get() const;
|
||||
|
||||
lldb::BreakpointSP &
|
||||
operator *();
|
||||
|
||||
const lldb::BreakpointSP &
|
||||
operator *() const;
|
||||
|
||||
#endif
|
||||
|
||||
static bool
|
||||
PrivateBreakpointHitCallback (void *baton,
|
||||
lldb_private::StoppointCallbackContext *context,
|
||||
lldb::user_id_t break_id,
|
||||
lldb::user_id_t break_loc_id);
|
||||
|
||||
lldb::BreakpointSP m_opaque_sp;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBBreakpoint_h_
|
||||
@@ -1,110 +0,0 @@
|
||||
//===-- SBBreakpointLocation.h ----------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBBreakpointLocation_h_
|
||||
#define LLDB_SBBreakpointLocation_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBBreakpoint.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBBreakpointLocation
|
||||
{
|
||||
public:
|
||||
|
||||
SBBreakpointLocation ();
|
||||
|
||||
SBBreakpointLocation (const lldb::SBBreakpointLocation &rhs);
|
||||
|
||||
~SBBreakpointLocation ();
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBBreakpointLocation &
|
||||
operator = (const lldb::SBBreakpointLocation &rhs);
|
||||
#endif
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
lldb::SBAddress
|
||||
GetAddress ();
|
||||
|
||||
lldb::addr_t
|
||||
GetLoadAddress ();
|
||||
|
||||
void
|
||||
SetEnabled(bool enabled);
|
||||
|
||||
bool
|
||||
IsEnabled ();
|
||||
|
||||
uint32_t
|
||||
GetIgnoreCount ();
|
||||
|
||||
void
|
||||
SetIgnoreCount (uint32_t n);
|
||||
|
||||
void
|
||||
SetCondition (const char *condition);
|
||||
|
||||
const char *
|
||||
GetCondition ();
|
||||
|
||||
void
|
||||
SetThreadID (lldb::tid_t sb_thread_id);
|
||||
|
||||
lldb::tid_t
|
||||
GetThreadID ();
|
||||
|
||||
void
|
||||
SetThreadIndex (uint32_t index);
|
||||
|
||||
uint32_t
|
||||
GetThreadIndex() const;
|
||||
|
||||
void
|
||||
SetThreadName (const char *thread_name);
|
||||
|
||||
const char *
|
||||
GetThreadName () const;
|
||||
|
||||
void
|
||||
SetQueueName (const char *queue_name);
|
||||
|
||||
const char *
|
||||
GetQueueName () const;
|
||||
|
||||
bool
|
||||
IsResolved ();
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description, DescriptionLevel level);
|
||||
|
||||
SBBreakpoint
|
||||
GetBreakpoint ();
|
||||
|
||||
#ifndef SWIG
|
||||
SBBreakpointLocation (const lldb::BreakpointLocationSP &break_loc_sp);
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class SBBreakpoint;
|
||||
friend class lldb_private::ScriptInterpreterPython;
|
||||
|
||||
void
|
||||
SetLocation (const lldb::BreakpointLocationSP &break_loc_sp);
|
||||
|
||||
lldb::BreakpointLocationSP m_opaque_sp;
|
||||
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBBreakpointLocation_h_
|
||||
@@ -1,106 +0,0 @@
|
||||
//===-- SBBroadcaster.h -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBBroadcaster_h_
|
||||
#define LLDB_SBBroadcaster_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBBroadcaster
|
||||
{
|
||||
public:
|
||||
SBBroadcaster ();
|
||||
|
||||
SBBroadcaster (const char *name);
|
||||
|
||||
SBBroadcaster (const SBBroadcaster &rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
const SBBroadcaster &
|
||||
operator = (const SBBroadcaster &rhs);
|
||||
#endif
|
||||
|
||||
~SBBroadcaster();
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
void
|
||||
BroadcastEventByType (uint32_t event_type, bool unique = false);
|
||||
|
||||
void
|
||||
BroadcastEvent (const lldb::SBEvent &event, bool unique = false);
|
||||
|
||||
void
|
||||
AddInitialEventsToListener (const lldb::SBListener &listener, uint32_t requested_events);
|
||||
|
||||
uint32_t
|
||||
AddListener (const lldb::SBListener &listener, uint32_t event_mask);
|
||||
|
||||
const char *
|
||||
GetName () const;
|
||||
|
||||
bool
|
||||
EventTypeHasListeners (uint32_t event_type);
|
||||
|
||||
bool
|
||||
RemoveListener (const lldb::SBListener &listener, uint32_t event_mask = UINT32_MAX);
|
||||
|
||||
#ifndef SWIG
|
||||
// This comparison is checking if the internal opaque pointer value
|
||||
// is equal to that in "rhs".
|
||||
bool
|
||||
operator == (const lldb::SBBroadcaster &rhs) const;
|
||||
|
||||
// This comparison is checking if the internal opaque pointer value
|
||||
// is not equal to that in "rhs".
|
||||
bool
|
||||
operator != (const lldb::SBBroadcaster &rhs) const;
|
||||
|
||||
// This comparison is checking if the internal opaque pointer value
|
||||
// is less than that in "rhs" so SBBroadcaster objects can be contained
|
||||
// in ordered containers.
|
||||
bool
|
||||
operator < (const lldb::SBBroadcaster &rhs) const;
|
||||
|
||||
#endif
|
||||
|
||||
protected:
|
||||
friend class SBCommandInterpreter;
|
||||
friend class SBCommunication;
|
||||
friend class SBEvent;
|
||||
friend class SBListener;
|
||||
friend class SBProcess;
|
||||
friend class SBTarget;
|
||||
|
||||
SBBroadcaster (lldb_private::Broadcaster *broadcaster, bool owns);
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
lldb_private::Broadcaster *
|
||||
get () const;
|
||||
|
||||
void
|
||||
reset (lldb_private::Broadcaster *broadcaster, bool owns);
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
lldb::BroadcasterSP m_opaque_sp;
|
||||
lldb_private::Broadcaster *m_opaque_ptr;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBBroadcaster_h_
|
||||
@@ -1,125 +0,0 @@
|
||||
//===-- SBCommandInterpreter.h ----------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBCommandInterpreter_h_
|
||||
#define LLDB_SBCommandInterpreter_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBCommandInterpreter
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
eBroadcastBitThreadShouldExit = (1 << 0),
|
||||
eBroadcastBitResetPrompt = (1 << 1),
|
||||
eBroadcastBitQuitCommandReceived = (1 << 2), // User entered quit
|
||||
eBroadcastBitAsynchronousOutputData = (1 << 3),
|
||||
eBroadcastBitAsynchronousErrorData = (1 << 4)
|
||||
};
|
||||
|
||||
SBCommandInterpreter (const lldb::SBCommandInterpreter &rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBCommandInterpreter &
|
||||
operator = (const lldb::SBCommandInterpreter &rhs);
|
||||
#endif
|
||||
|
||||
~SBCommandInterpreter ();
|
||||
|
||||
static const char *
|
||||
GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type);
|
||||
|
||||
static const char *
|
||||
GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type);
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
bool
|
||||
CommandExists (const char *cmd);
|
||||
|
||||
bool
|
||||
AliasExists (const char *cmd);
|
||||
|
||||
lldb::SBBroadcaster
|
||||
GetBroadcaster ();
|
||||
|
||||
bool
|
||||
HasCommands ();
|
||||
|
||||
bool
|
||||
HasAliases ();
|
||||
|
||||
bool
|
||||
HasAliasOptions ();
|
||||
|
||||
lldb::SBProcess
|
||||
GetProcess ();
|
||||
|
||||
ssize_t
|
||||
WriteToScriptInterpreter (const char *src);
|
||||
|
||||
ssize_t
|
||||
WriteToScriptInterpreter (const char *src, size_t src_len);
|
||||
|
||||
void
|
||||
SourceInitFileInHomeDirectory (lldb::SBCommandReturnObject &result);
|
||||
|
||||
void
|
||||
SourceInitFileInCurrentWorkingDirectory (lldb::SBCommandReturnObject &result);
|
||||
|
||||
lldb::ReturnStatus
|
||||
HandleCommand (const char *command_line, lldb::SBCommandReturnObject &result, bool add_to_history = false);
|
||||
|
||||
#ifndef SWIG
|
||||
// This interface is not useful in SWIG, since the cursor & last_char arguments are string pointers INTO current_line
|
||||
// and you can't do that in a scripting language interface in general...
|
||||
int
|
||||
HandleCompletion (const char *current_line,
|
||||
const char *cursor,
|
||||
const char *last_char,
|
||||
int match_start_point,
|
||||
int max_return_elements,
|
||||
lldb::SBStringList &matches);
|
||||
#endif
|
||||
int
|
||||
HandleCompletion (const char *current_line,
|
||||
uint32_t cursor_pos,
|
||||
int match_start_point,
|
||||
int max_return_elements,
|
||||
lldb::SBStringList &matches);
|
||||
|
||||
protected:
|
||||
|
||||
lldb_private::CommandInterpreter &
|
||||
ref ();
|
||||
|
||||
lldb_private::CommandInterpreter *
|
||||
get ();
|
||||
|
||||
void
|
||||
reset (lldb_private::CommandInterpreter *);
|
||||
private:
|
||||
friend class SBDebugger;
|
||||
|
||||
SBCommandInterpreter (lldb_private::CommandInterpreter *interpreter_ptr = NULL); // Access using SBDebugger::GetCommandInterpreter();
|
||||
|
||||
static void
|
||||
InitializeSWIG ();
|
||||
|
||||
lldb_private::CommandInterpreter *m_opaque_ptr;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBCommandInterpreter_h_
|
||||
@@ -1,121 +0,0 @@
|
||||
//===-- SBCommandReturnObject.h ---------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBCommandReturnObject_h_
|
||||
#define LLDB_SBCommandReturnObject_h_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBCommandReturnObject
|
||||
{
|
||||
public:
|
||||
|
||||
SBCommandReturnObject ();
|
||||
|
||||
SBCommandReturnObject (const lldb::SBCommandReturnObject &rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
const lldb::SBCommandReturnObject &
|
||||
operator = (const lldb::SBCommandReturnObject &rhs);
|
||||
|
||||
|
||||
SBCommandReturnObject (lldb_private::CommandReturnObject *ptr);
|
||||
|
||||
lldb_private::CommandReturnObject *
|
||||
Release ();
|
||||
#endif
|
||||
|
||||
~SBCommandReturnObject ();
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
const char *
|
||||
GetOutput ();
|
||||
|
||||
const char *
|
||||
GetError ();
|
||||
|
||||
size_t
|
||||
PutOutput (FILE *fh);
|
||||
|
||||
size_t
|
||||
GetOutputSize ();
|
||||
|
||||
size_t
|
||||
GetErrorSize ();
|
||||
|
||||
size_t
|
||||
PutError (FILE *fh);
|
||||
|
||||
void
|
||||
Clear();
|
||||
|
||||
lldb::ReturnStatus
|
||||
GetStatus();
|
||||
|
||||
bool
|
||||
Succeeded ();
|
||||
|
||||
bool
|
||||
HasResult ();
|
||||
|
||||
void
|
||||
AppendMessage (const char *message);
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
void
|
||||
SetImmediateOutputFile (FILE *fh);
|
||||
|
||||
void
|
||||
SetImmediateErrorFile (FILE *fh);
|
||||
|
||||
void
|
||||
PutCString(const char* string, int len = -1);
|
||||
|
||||
size_t
|
||||
Printf(const char* format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
|
||||
protected:
|
||||
friend class SBCommandInterpreter;
|
||||
friend class SBOptions;
|
||||
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
lldb_private::CommandReturnObject *
|
||||
operator->() const;
|
||||
|
||||
lldb_private::CommandReturnObject *
|
||||
get() const;
|
||||
|
||||
lldb_private::CommandReturnObject &
|
||||
operator*() const;
|
||||
|
||||
lldb_private::CommandReturnObject &
|
||||
ref() const;
|
||||
|
||||
#endif
|
||||
void
|
||||
SetLLDBObjectPtr (lldb_private::CommandReturnObject *ptr);
|
||||
|
||||
private:
|
||||
std::auto_ptr<lldb_private::CommandReturnObject> m_opaque_ap;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBCommandReturnObject_h_
|
||||
@@ -1,97 +0,0 @@
|
||||
//===-- SBCommunication.h ---------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBCommunication_h_
|
||||
#define LLDB_SBCommunication_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBError.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBCommunication
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
eBroadcastBitDisconnected = (1 << 0), ///< Sent when the communications connection is lost.
|
||||
eBroadcastBitReadThreadGotBytes = (1 << 1), ///< Sent by the read thread when bytes become available.
|
||||
eBroadcastBitReadThreadDidExit = (1 << 2), ///< Sent by the read thread when it exits to inform clients.
|
||||
eBroadcastBitReadThreadShouldExit = (1 << 3), ///< Sent by clients that need to cancel the read thread.
|
||||
eBroadcastBitPacketAvailable = (1 << 4), ///< Sent when data received makes a complete packet.
|
||||
eAllEventBits = 0xffffffff
|
||||
};
|
||||
|
||||
typedef void (*ReadThreadBytesReceived) (void *baton, const void *src, size_t src_len);
|
||||
|
||||
SBCommunication ();
|
||||
SBCommunication (const char * broadcaster_name);
|
||||
~SBCommunication ();
|
||||
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
lldb::SBBroadcaster
|
||||
GetBroadcaster ();
|
||||
|
||||
lldb::ConnectionStatus
|
||||
AdoptFileDesriptor (int fd, bool owns_fd);
|
||||
|
||||
lldb::ConnectionStatus
|
||||
Connect (const char *url);
|
||||
|
||||
lldb::ConnectionStatus
|
||||
Disconnect ();
|
||||
|
||||
bool
|
||||
IsConnected () const;
|
||||
|
||||
bool
|
||||
GetCloseOnEOF ();
|
||||
|
||||
void
|
||||
SetCloseOnEOF (bool b);
|
||||
|
||||
size_t
|
||||
Read (void *dst,
|
||||
size_t dst_len,
|
||||
uint32_t timeout_usec,
|
||||
lldb::ConnectionStatus &status);
|
||||
|
||||
size_t
|
||||
Write (const void *src,
|
||||
size_t src_len,
|
||||
lldb::ConnectionStatus &status);
|
||||
|
||||
bool
|
||||
ReadThreadStart ();
|
||||
|
||||
bool
|
||||
ReadThreadStop ();
|
||||
|
||||
bool
|
||||
ReadThreadIsRunning ();
|
||||
|
||||
bool
|
||||
SetReadThreadBytesReceivedCallback (ReadThreadBytesReceived callback,
|
||||
void *callback_baton);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (SBCommunication);
|
||||
|
||||
lldb_private::Communication *m_opaque;
|
||||
bool m_opaque_owned;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBCommunication_h_
|
||||
@@ -1,98 +0,0 @@
|
||||
//===-- SBCompileUnit.h -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBCompileUnit_h_
|
||||
#define LLDB_SBCompileUnit_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBFileSpec.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBCompileUnit
|
||||
{
|
||||
public:
|
||||
|
||||
SBCompileUnit ();
|
||||
|
||||
SBCompileUnit (const lldb::SBCompileUnit &rhs);
|
||||
|
||||
~SBCompileUnit ();
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBCompileUnit &
|
||||
operator = (const lldb::SBCompileUnit &rhs);
|
||||
#endif
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
lldb::SBFileSpec
|
||||
GetFileSpec () const;
|
||||
|
||||
uint32_t
|
||||
GetNumLineEntries () const;
|
||||
|
||||
lldb::SBLineEntry
|
||||
GetLineEntryAtIndex (uint32_t idx) const;
|
||||
|
||||
uint32_t
|
||||
FindLineEntryIndex (uint32_t start_idx,
|
||||
uint32_t line,
|
||||
lldb::SBFileSpec *inline_file_spec) const;
|
||||
|
||||
uint32_t
|
||||
FindLineEntryIndex (uint32_t start_idx,
|
||||
uint32_t line,
|
||||
lldb::SBFileSpec *inline_file_spec,
|
||||
bool exact) const;
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
bool
|
||||
operator == (const lldb::SBCompileUnit &rhs) const;
|
||||
|
||||
bool
|
||||
operator != (const lldb::SBCompileUnit &rhs) const;
|
||||
|
||||
#endif
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
private:
|
||||
friend class SBAddress;
|
||||
friend class SBFrame;
|
||||
friend class SBSymbolContext;
|
||||
|
||||
SBCompileUnit (lldb_private::CompileUnit *lldb_object_ptr);
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
const lldb_private::CompileUnit *
|
||||
operator->() const;
|
||||
|
||||
const lldb_private::CompileUnit &
|
||||
operator*() const;
|
||||
|
||||
lldb_private::CompileUnit *
|
||||
get ();
|
||||
|
||||
void
|
||||
reset (lldb_private::CompileUnit *lldb_object_ptr);
|
||||
|
||||
#endif
|
||||
|
||||
lldb_private::CompileUnit *m_opaque_ptr;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBCompileUnit_h_
|
||||
@@ -1,138 +0,0 @@
|
||||
//===-- SBData.h -----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBData_h_
|
||||
#define LLDB_SBData_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBData
|
||||
{
|
||||
public:
|
||||
|
||||
SBData ();
|
||||
|
||||
SBData (const SBData &rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
const SBData &
|
||||
operator = (const SBData &rhs);
|
||||
#endif
|
||||
|
||||
~SBData ();
|
||||
|
||||
uint8_t
|
||||
GetAddressByteSize ();
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
bool
|
||||
IsValid();
|
||||
|
||||
size_t
|
||||
GetByteSize ();
|
||||
|
||||
lldb::ByteOrder
|
||||
GetByteOrder();
|
||||
|
||||
float
|
||||
GetFloat (lldb::SBError& error, uint32_t offset);
|
||||
|
||||
double
|
||||
GetDouble (lldb::SBError& error, uint32_t offset);
|
||||
|
||||
long double
|
||||
GetLongDouble (lldb::SBError& error, uint32_t offset);
|
||||
|
||||
lldb::addr_t
|
||||
GetAddress (lldb::SBError& error, uint32_t offset);
|
||||
|
||||
uint8_t
|
||||
GetUnsignedInt8 (lldb::SBError& error, uint32_t offset);
|
||||
|
||||
uint16_t
|
||||
GetUnsignedInt16 (lldb::SBError& error, uint32_t offset);
|
||||
|
||||
uint32_t
|
||||
GetUnsignedInt32 (lldb::SBError& error, uint32_t offset);
|
||||
|
||||
uint64_t
|
||||
GetUnsignedInt64 (lldb::SBError& error, uint32_t offset);
|
||||
|
||||
int8_t
|
||||
GetSignedInt8 (lldb::SBError& error, uint32_t offset);
|
||||
|
||||
int16_t
|
||||
GetSignedInt16 (lldb::SBError& error, uint32_t offset);
|
||||
|
||||
int32_t
|
||||
GetSignedInt32 (lldb::SBError& error, uint32_t offset);
|
||||
|
||||
int64_t
|
||||
GetSignedInt64 (lldb::SBError& error, uint32_t offset);
|
||||
|
||||
const char*
|
||||
GetString (lldb::SBError& error, uint32_t offset);
|
||||
|
||||
size_t
|
||||
ReadRawData (lldb::SBError& error,
|
||||
uint32_t offset,
|
||||
void *buf,
|
||||
size_t size);
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description, lldb::addr_t base_addr = LLDB_INVALID_ADDRESS);
|
||||
|
||||
// it would be nice to have SetData(SBError, const void*, size_t) when endianness and address size can be
|
||||
// inferred from the existing DataExtractor, but having two SetData() signatures triggers a SWIG bug where
|
||||
// the typemap isn't applied before resolving the overload, and thus the right function never gets called
|
||||
void
|
||||
SetData(lldb::SBError& error, const void *buf, size_t size, lldb::ByteOrder endian, uint8_t addr_size);
|
||||
|
||||
// see SetData() for why we don't have Append(const void* buf, size_t size)
|
||||
bool
|
||||
Append(const SBData& rhs);
|
||||
|
||||
protected:
|
||||
|
||||
#ifndef SWIG
|
||||
// Mimic shared pointer...
|
||||
lldb_private::DataExtractor *
|
||||
get() const;
|
||||
|
||||
lldb_private::DataExtractor *
|
||||
operator->() const;
|
||||
|
||||
lldb::DataExtractorSP &
|
||||
operator*();
|
||||
|
||||
const lldb::DataExtractorSP &
|
||||
operator*() const;
|
||||
#endif
|
||||
|
||||
SBData (const lldb::DataExtractorSP &data_sp);
|
||||
|
||||
void
|
||||
SetOpaque (const lldb::DataExtractorSP &data_sp);
|
||||
|
||||
private:
|
||||
friend class SBInstruction;
|
||||
friend class SBSection;
|
||||
friend class SBValue;
|
||||
|
||||
lldb::DataExtractorSP m_opaque_sp;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBData_h_
|
||||
@@ -1,275 +0,0 @@
|
||||
//===-- SBDebugger.h --------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBDebugger_h_
|
||||
#define LLDB_SBDebugger_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include <stdio.h>
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBDebugger
|
||||
{
|
||||
public:
|
||||
|
||||
static void
|
||||
Initialize();
|
||||
|
||||
static void
|
||||
Terminate();
|
||||
|
||||
// Deprecated, use the one that takes a source_init_files bool.
|
||||
static lldb::SBDebugger
|
||||
Create();
|
||||
|
||||
static lldb::SBDebugger
|
||||
Create(bool source_init_files);
|
||||
|
||||
static void
|
||||
Destroy (lldb::SBDebugger &debugger);
|
||||
|
||||
SBDebugger();
|
||||
|
||||
SBDebugger(const lldb::SBDebugger &rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
SBDebugger(const lldb::DebuggerSP &debugger_sp);
|
||||
|
||||
lldb::SBDebugger &
|
||||
operator = (const lldb::SBDebugger &rhs);
|
||||
#endif
|
||||
|
||||
~SBDebugger();
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
void
|
||||
SetAsync (bool b);
|
||||
|
||||
bool
|
||||
GetAsync ();
|
||||
|
||||
void
|
||||
SkipLLDBInitFiles (bool b);
|
||||
|
||||
void
|
||||
SkipAppInitFiles (bool b);
|
||||
|
||||
void
|
||||
SetInputFileHandle (FILE *f, bool transfer_ownership);
|
||||
|
||||
void
|
||||
SetOutputFileHandle (FILE *f, bool transfer_ownership);
|
||||
|
||||
void
|
||||
SetErrorFileHandle (FILE *f, bool transfer_ownership);
|
||||
|
||||
FILE *
|
||||
GetInputFileHandle ();
|
||||
|
||||
FILE *
|
||||
GetOutputFileHandle ();
|
||||
|
||||
FILE *
|
||||
GetErrorFileHandle ();
|
||||
|
||||
lldb::SBCommandInterpreter
|
||||
GetCommandInterpreter ();
|
||||
|
||||
void
|
||||
HandleCommand (const char *command);
|
||||
|
||||
lldb::SBListener
|
||||
GetListener ();
|
||||
|
||||
void
|
||||
HandleProcessEvent (const lldb::SBProcess &process,
|
||||
const lldb::SBEvent &event,
|
||||
FILE *out,
|
||||
FILE *err);
|
||||
|
||||
lldb::SBTarget
|
||||
CreateTarget (const char *filename,
|
||||
const char *target_triple,
|
||||
const char *platform_name,
|
||||
bool add_dependent_modules,
|
||||
lldb::SBError& error);
|
||||
|
||||
lldb::SBTarget
|
||||
CreateTargetWithFileAndTargetTriple (const char *filename,
|
||||
const char *target_triple);
|
||||
|
||||
lldb::SBTarget
|
||||
CreateTargetWithFileAndArch (const char *filename,
|
||||
const char *archname);
|
||||
|
||||
lldb::SBTarget
|
||||
CreateTarget (const char *filename);
|
||||
|
||||
// Return true if target is deleted from the target list of the debugger.
|
||||
bool
|
||||
DeleteTarget (lldb::SBTarget &target);
|
||||
|
||||
lldb::SBTarget
|
||||
GetTargetAtIndex (uint32_t idx);
|
||||
|
||||
lldb::SBTarget
|
||||
FindTargetWithProcessID (pid_t pid);
|
||||
|
||||
lldb::SBTarget
|
||||
FindTargetWithFileAndArch (const char *filename,
|
||||
const char *arch);
|
||||
|
||||
uint32_t
|
||||
GetNumTargets ();
|
||||
|
||||
lldb::SBTarget
|
||||
GetSelectedTarget ();
|
||||
|
||||
void
|
||||
SetSelectedTarget (SBTarget& target);
|
||||
|
||||
lldb::SBSourceManager
|
||||
GetSourceManager ();
|
||||
|
||||
// REMOVE: just for a quick fix, need to expose platforms through
|
||||
// SBPlatform from this class.
|
||||
lldb::SBError
|
||||
SetCurrentPlatform (const char *platform_name);
|
||||
|
||||
bool
|
||||
SetCurrentPlatformSDKRoot (const char *sysroot);
|
||||
|
||||
// FIXME: Once we get the set show stuff in place, the driver won't need
|
||||
// an interface to the Set/Get UseExternalEditor.
|
||||
bool
|
||||
SetUseExternalEditor (bool input);
|
||||
|
||||
bool
|
||||
GetUseExternalEditor ();
|
||||
|
||||
static bool
|
||||
GetDefaultArchitecture (char *arch_name, size_t arch_name_len);
|
||||
|
||||
static bool
|
||||
SetDefaultArchitecture (const char *arch_name);
|
||||
|
||||
lldb::ScriptLanguage
|
||||
GetScriptingLanguage (const char *script_language_name);
|
||||
|
||||
static const char *
|
||||
GetVersionString ();
|
||||
|
||||
static const char *
|
||||
StateAsCString (lldb::StateType state);
|
||||
|
||||
static bool
|
||||
StateIsRunningState (lldb::StateType state);
|
||||
|
||||
static bool
|
||||
StateIsStoppedState (lldb::StateType state);
|
||||
|
||||
void
|
||||
DispatchInput (void *baton, const void *data, size_t data_len);
|
||||
|
||||
void
|
||||
DispatchInputInterrupt ();
|
||||
|
||||
void
|
||||
DispatchInputEndOfFile ();
|
||||
|
||||
void
|
||||
PushInputReader (lldb::SBInputReader &reader);
|
||||
|
||||
void
|
||||
NotifyTopInputReader (lldb::InputReaderAction notification);
|
||||
|
||||
bool
|
||||
InputReaderIsTopReader (const lldb::SBInputReader &reader);
|
||||
|
||||
const char *
|
||||
GetInstanceName ();
|
||||
|
||||
static SBDebugger
|
||||
FindDebuggerWithID (int id);
|
||||
|
||||
static lldb::SBError
|
||||
SetInternalVariable (const char *var_name, const char *value, const char *debugger_instance_name);
|
||||
|
||||
static lldb::SBStringList
|
||||
GetInternalVariableValue (const char *var_name, const char *debugger_instance_name);
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
uint32_t
|
||||
GetTerminalWidth () const;
|
||||
|
||||
void
|
||||
SetTerminalWidth (uint32_t term_width);
|
||||
|
||||
lldb::user_id_t
|
||||
GetID ();
|
||||
|
||||
const char *
|
||||
GetPrompt() const;
|
||||
|
||||
void
|
||||
SetPrompt (const char *prompt);
|
||||
|
||||
lldb::ScriptLanguage
|
||||
GetScriptLanguage() const;
|
||||
|
||||
void
|
||||
SetScriptLanguage (lldb::ScriptLanguage script_lang);
|
||||
|
||||
bool
|
||||
GetCloseInputOnEOF () const;
|
||||
|
||||
void
|
||||
SetCloseInputOnEOF (bool b);
|
||||
|
||||
private:
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
friend class SBInputReader;
|
||||
friend class SBProcess;
|
||||
friend class SBSourceManager;
|
||||
friend class SBTarget;
|
||||
|
||||
lldb::SBTarget
|
||||
FindTargetWithLLDBProcess (const lldb::ProcessSP &processSP);
|
||||
|
||||
void
|
||||
reset (const lldb::DebuggerSP &debugger_sp);
|
||||
|
||||
lldb_private::Debugger *
|
||||
get () const;
|
||||
|
||||
lldb_private::Debugger &
|
||||
ref () const;
|
||||
|
||||
const lldb::DebuggerSP &
|
||||
get_sp () const;
|
||||
#endif
|
||||
|
||||
lldb::DebuggerSP m_opaque_sp;
|
||||
|
||||
}; // class SBDebugger
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBDebugger_h_
|
||||
@@ -1,70 +0,0 @@
|
||||
//===-- SBDefines.h ---------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBDefines_h_
|
||||
#define LLDB_SBDefines_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
|
||||
#include "lldb/lldb-defines.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
#include "lldb/lldb-forward.h"
|
||||
#include "lldb/lldb-forward-rtti.h"
|
||||
#include "lldb/lldb-types.h"
|
||||
|
||||
// Forward Declarations
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBAddress;
|
||||
class SBBlock;
|
||||
class SBBreakpoint;
|
||||
class SBBreakpointLocation;
|
||||
class SBBroadcaster;
|
||||
class SBCommandInterpreter;
|
||||
class SBCommandReturnObject;
|
||||
class SBCommunication;
|
||||
class SBCompileUnit;
|
||||
class SBData;
|
||||
class SBDebugger;
|
||||
class SBError;
|
||||
class SBEvent;
|
||||
class SBEventList;
|
||||
class SBFileSpec;
|
||||
class SBFileSpecList;
|
||||
class SBFrame;
|
||||
class SBFunction;
|
||||
class SBHostOS;
|
||||
class SBInputReader;
|
||||
class SBInstruction;
|
||||
class SBInstructionList;
|
||||
class SBLineEntry;
|
||||
class SBListener;
|
||||
class SBModule;
|
||||
class SBProcess;
|
||||
class SBSourceManager;
|
||||
class SBStream;
|
||||
class SBStringList;
|
||||
class SBSymbol;
|
||||
class SBSymbolContext;
|
||||
class SBSymbolContextList;
|
||||
class SBTarget;
|
||||
class SBThread;
|
||||
class SBType;
|
||||
class SBTypeList;
|
||||
class SBValue;
|
||||
class SBValueList;
|
||||
class SBWatchpoint;
|
||||
|
||||
}
|
||||
|
||||
#endif // LLDB_SBDefines_h_
|
||||
@@ -1,114 +0,0 @@
|
||||
//===-- SBError.h -----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBError_h_
|
||||
#define LLDB_SBError_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBError {
|
||||
public:
|
||||
SBError ();
|
||||
|
||||
SBError (const lldb::SBError &rhs);
|
||||
|
||||
~SBError();
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
const SBError &
|
||||
operator =(const lldb::SBError &rhs);
|
||||
|
||||
#endif
|
||||
|
||||
const char *
|
||||
GetCString () const;
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
bool
|
||||
Fail () const;
|
||||
|
||||
bool
|
||||
Success () const;
|
||||
|
||||
uint32_t
|
||||
GetError () const;
|
||||
|
||||
lldb::ErrorType
|
||||
GetType () const;
|
||||
|
||||
void
|
||||
SetError (uint32_t err, lldb::ErrorType type);
|
||||
|
||||
void
|
||||
SetErrorToErrno ();
|
||||
|
||||
void
|
||||
SetErrorToGenericError ();
|
||||
|
||||
void
|
||||
SetErrorString (const char *err_str);
|
||||
|
||||
int
|
||||
SetErrorStringWithFormat (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
protected:
|
||||
|
||||
#ifndef SWIG
|
||||
friend class SBArguments;
|
||||
friend class SBData;
|
||||
friend class SBDebugger;
|
||||
friend class SBCommunication;
|
||||
friend class SBHostOS;
|
||||
friend class SBInputReader;
|
||||
friend class SBProcess;
|
||||
friend class SBThread;
|
||||
friend class SBTarget;
|
||||
friend class SBValue;
|
||||
friend class SBWatchpoint;
|
||||
|
||||
lldb_private::Error *
|
||||
get();
|
||||
|
||||
lldb_private::Error *
|
||||
operator->();
|
||||
|
||||
const lldb_private::Error &
|
||||
operator*() const;
|
||||
|
||||
lldb_private::Error &
|
||||
ref();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
SetError (const lldb_private::Error &lldb_error);
|
||||
|
||||
private:
|
||||
std::auto_ptr<lldb_private::Error> m_opaque_ap;
|
||||
|
||||
void
|
||||
CreateIfNeeded ();
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBError_h_
|
||||
@@ -1,107 +0,0 @@
|
||||
//===-- SBEvent.h -----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBEvent_h_
|
||||
#define LLDB_SBEvent_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBBroadcaster;
|
||||
|
||||
class SBEvent
|
||||
{
|
||||
public:
|
||||
SBEvent();
|
||||
|
||||
SBEvent (const lldb::SBEvent &rhs);
|
||||
|
||||
// Make an event that contains a C string.
|
||||
SBEvent (uint32_t event, const char *cstr, uint32_t cstr_len);
|
||||
|
||||
~SBEvent();
|
||||
|
||||
#ifndef SWIG
|
||||
const SBEvent &
|
||||
operator = (const lldb::SBEvent &rhs);
|
||||
#endif
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
const char *
|
||||
GetDataFlavor ();
|
||||
|
||||
uint32_t
|
||||
GetType () const;
|
||||
|
||||
lldb::SBBroadcaster
|
||||
GetBroadcaster () const;
|
||||
|
||||
#ifndef SWIG
|
||||
bool
|
||||
BroadcasterMatchesPtr (const lldb::SBBroadcaster *broadcaster);
|
||||
#endif
|
||||
|
||||
bool
|
||||
BroadcasterMatchesRef (const lldb::SBBroadcaster &broadcaster);
|
||||
|
||||
void
|
||||
Clear();
|
||||
|
||||
static const char *
|
||||
GetCStringFromEvent (const lldb::SBEvent &event);
|
||||
|
||||
#ifndef SWIG
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
#endif
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description) const;
|
||||
|
||||
protected:
|
||||
friend class SBListener;
|
||||
friend class SBBroadcaster;
|
||||
friend class SBBreakpoint;
|
||||
friend class SBDebugger;
|
||||
friend class SBProcess;
|
||||
|
||||
SBEvent (lldb::EventSP &event_sp);
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
lldb::EventSP &
|
||||
GetSP () const;
|
||||
|
||||
void
|
||||
reset (lldb::EventSP &event_sp);
|
||||
|
||||
void
|
||||
reset (lldb_private::Event* event);
|
||||
|
||||
lldb_private::Event *
|
||||
get () const;
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
mutable lldb::EventSP m_event_sp;
|
||||
mutable lldb_private::Event *m_opaque_ptr;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBEvent_h_
|
||||
@@ -1,95 +0,0 @@
|
||||
//===-- SBFileSpec.h --------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBFileSpec_h_
|
||||
#define LLDB_SBFileSpec_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBFileSpec
|
||||
{
|
||||
public:
|
||||
SBFileSpec ();
|
||||
|
||||
SBFileSpec (const lldb::SBFileSpec &rhs);
|
||||
|
||||
SBFileSpec (const char *path);// Deprected, use SBFileSpec (const char *path, bool resolve)
|
||||
|
||||
SBFileSpec (const char *path, bool resolve);
|
||||
|
||||
~SBFileSpec ();
|
||||
|
||||
#ifndef SWIG
|
||||
const SBFileSpec &
|
||||
operator = (const lldb::SBFileSpec &rhs);
|
||||
#endif
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
bool
|
||||
Exists () const;
|
||||
|
||||
bool
|
||||
ResolveExecutableLocation ();
|
||||
|
||||
const char *
|
||||
GetFilename() const;
|
||||
|
||||
const char *
|
||||
GetDirectory() const;
|
||||
|
||||
uint32_t
|
||||
GetPath (char *dst_path, size_t dst_len) const;
|
||||
|
||||
static int
|
||||
ResolvePath (const char *src_path, char *dst_path, size_t dst_len);
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description) const;
|
||||
|
||||
private:
|
||||
friend class SBBlock;
|
||||
friend class SBCompileUnit;
|
||||
friend class SBFileSpecList;
|
||||
friend class SBHostOS;
|
||||
friend class SBLineEntry;
|
||||
friend class SBModule;
|
||||
friend class SBProcess;
|
||||
friend class SBSourceManager;
|
||||
friend class SBThread;
|
||||
friend class SBTarget;
|
||||
|
||||
void
|
||||
SetFileSpec (const lldb_private::FileSpec& fs);
|
||||
#ifndef SWIG
|
||||
|
||||
const lldb_private::FileSpec *
|
||||
operator->() const;
|
||||
|
||||
const lldb_private::FileSpec *
|
||||
get() const;
|
||||
|
||||
const lldb_private::FileSpec &
|
||||
operator*() const;
|
||||
|
||||
const lldb_private::FileSpec &
|
||||
ref() const;
|
||||
|
||||
#endif
|
||||
|
||||
std::auto_ptr <lldb_private::FileSpec> m_opaque_ap;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBFileSpec_h_
|
||||
@@ -1,78 +0,0 @@
|
||||
//===-- SBFileSpecList.h --------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBFileSpecList_h_
|
||||
#define LLDB_SBFileSpecList_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBFileSpecList
|
||||
{
|
||||
public:
|
||||
SBFileSpecList ();
|
||||
|
||||
SBFileSpecList (const lldb::SBFileSpecList &rhs);
|
||||
|
||||
~SBFileSpecList ();
|
||||
|
||||
#ifndef SWIG
|
||||
const SBFileSpecList &
|
||||
operator = (const lldb::SBFileSpecList &rhs);
|
||||
#endif
|
||||
|
||||
uint32_t
|
||||
GetSize () const;
|
||||
|
||||
bool
|
||||
GetDescription (SBStream &description) const;
|
||||
|
||||
void
|
||||
Append (const SBFileSpec &sb_file);
|
||||
|
||||
bool
|
||||
AppendIfUnique (const SBFileSpec &sb_file);
|
||||
|
||||
void
|
||||
Clear();
|
||||
|
||||
uint32_t
|
||||
FindFileIndex (uint32_t idx, const SBFileSpec &sb_file, bool full);
|
||||
|
||||
const SBFileSpec
|
||||
GetFileSpecAtIndex (uint32_t idx) const;
|
||||
|
||||
private:
|
||||
|
||||
friend class SBTarget;
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
const lldb_private::FileSpecList *
|
||||
operator->() const;
|
||||
|
||||
const lldb_private::FileSpecList *
|
||||
get() const;
|
||||
|
||||
const lldb_private::FileSpecList &
|
||||
operator*() const;
|
||||
|
||||
const lldb_private::FileSpecList &
|
||||
ref() const;
|
||||
|
||||
#endif
|
||||
|
||||
std::auto_ptr <lldb_private::FileSpecList> m_opaque_ap;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBFileSpecList_h_
|
||||
@@ -1,232 +0,0 @@
|
||||
//===-- SBFrame.h -----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBFrame_h_
|
||||
#define LLDB_SBFrame_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBValueList.h"
|
||||
#include "lldb/API/SBWatchpoint.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBValue;
|
||||
|
||||
class SBFrame
|
||||
{
|
||||
public:
|
||||
SBFrame ();
|
||||
|
||||
SBFrame (const lldb::SBFrame &rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBFrame &
|
||||
operator =(const lldb::SBFrame &rhs);
|
||||
#endif
|
||||
|
||||
~SBFrame();
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
uint32_t
|
||||
GetFrameID () const;
|
||||
|
||||
lldb::addr_t
|
||||
GetPC () const;
|
||||
|
||||
bool
|
||||
SetPC (lldb::addr_t new_pc);
|
||||
|
||||
lldb::addr_t
|
||||
GetSP () const;
|
||||
|
||||
lldb::addr_t
|
||||
GetFP () const;
|
||||
|
||||
lldb::SBAddress
|
||||
GetPCAddress () const;
|
||||
|
||||
lldb::SBSymbolContext
|
||||
GetSymbolContext (uint32_t resolve_scope) const;
|
||||
|
||||
lldb::SBModule
|
||||
GetModule () const;
|
||||
|
||||
lldb::SBCompileUnit
|
||||
GetCompileUnit () const;
|
||||
|
||||
lldb::SBFunction
|
||||
GetFunction () const;
|
||||
|
||||
lldb::SBSymbol
|
||||
GetSymbol () const;
|
||||
|
||||
/// Gets the deepest block that contains the frame PC.
|
||||
///
|
||||
/// See also GetFrameBlock().
|
||||
lldb::SBBlock
|
||||
GetBlock () const;
|
||||
|
||||
/// Get the appropriate function name for this frame. Inlined functions in
|
||||
/// LLDB are represented by Blocks that have inlined function information, so
|
||||
/// just looking at the SBFunction or SBSymbol for a frame isn't enough.
|
||||
/// This function will return the appriopriate function, symbol or inlined
|
||||
/// function name for the frame.
|
||||
///
|
||||
/// This function returns:
|
||||
/// - the name of the inlined function (if there is one)
|
||||
/// - the name of the concrete function (if there is one)
|
||||
/// - the name of the symbol (if there is one)
|
||||
/// - NULL
|
||||
///
|
||||
/// See also IsInlined().
|
||||
const char *
|
||||
GetFunctionName();
|
||||
|
||||
/// Return true if this frame represents an inlined function.
|
||||
///
|
||||
/// See also GetFunctionName().
|
||||
bool
|
||||
IsInlined();
|
||||
|
||||
/// The version that doesn't supply a 'use_dynamic' value will use the
|
||||
/// target's default.
|
||||
lldb::SBValue
|
||||
EvaluateExpression (const char *expr);
|
||||
|
||||
lldb::SBValue
|
||||
EvaluateExpression (const char *expr, lldb::DynamicValueType use_dynamic);
|
||||
|
||||
/// Gets the lexical block that defines the stack frame. Another way to think
|
||||
/// of this is it will return the block that contains all of the variables
|
||||
/// for a stack frame. Inlined functions are represented as SBBlock objects
|
||||
/// that have inlined function information: the name of the inlined function,
|
||||
/// where it was called from. The block that is returned will be the first
|
||||
/// block at or above the block for the PC (SBFrame::GetBlock()) that defines
|
||||
/// the scope of the frame. When a function contains no inlined functions,
|
||||
/// this will be the top most lexical block that defines the function.
|
||||
/// When a function has inlined functions and the PC is currently
|
||||
/// in one of those inlined functions, this method will return the inlined
|
||||
/// block that defines this frame. If the PC isn't currently in an inlined
|
||||
/// function, the lexical block that defines the function is returned.
|
||||
lldb::SBBlock
|
||||
GetFrameBlock () const;
|
||||
|
||||
lldb::SBLineEntry
|
||||
GetLineEntry () const;
|
||||
|
||||
lldb::SBThread
|
||||
GetThread () const;
|
||||
|
||||
const char *
|
||||
Disassemble () const;
|
||||
|
||||
void
|
||||
Clear();
|
||||
|
||||
#ifndef SWIG
|
||||
bool
|
||||
operator == (const lldb::SBFrame &rhs) const;
|
||||
|
||||
bool
|
||||
operator != (const lldb::SBFrame &rhs) const;
|
||||
|
||||
#endif
|
||||
|
||||
/// The version that doesn't supply a 'use_dynamic' value will use the
|
||||
/// target's default.
|
||||
lldb::SBValueList
|
||||
GetVariables (bool arguments,
|
||||
bool locals,
|
||||
bool statics,
|
||||
bool in_scope_only);
|
||||
|
||||
lldb::SBValueList
|
||||
GetVariables (bool arguments,
|
||||
bool locals,
|
||||
bool statics,
|
||||
bool in_scope_only,
|
||||
lldb::DynamicValueType use_dynamic);
|
||||
|
||||
lldb::SBValueList
|
||||
GetRegisters ();
|
||||
|
||||
/// The version that doesn't supply a 'use_dynamic' value will use the
|
||||
/// target's default.
|
||||
lldb::SBValue
|
||||
FindVariable (const char *var_name);
|
||||
|
||||
lldb::SBValue
|
||||
FindVariable (const char *var_name, lldb::DynamicValueType use_dynamic);
|
||||
|
||||
/// Find variables, register sets, registers, or persistent variables using
|
||||
/// the frame as the scope.
|
||||
///
|
||||
/// The version that doesn't supply a 'use_dynamic' value will use the
|
||||
/// target's default.
|
||||
lldb::SBValue
|
||||
FindValue (const char *name, ValueType value_type);
|
||||
|
||||
lldb::SBValue
|
||||
FindValue (const char *name, ValueType value_type, lldb::DynamicValueType use_dynamic);
|
||||
|
||||
/// Find and watch a variable using the frame as the scope.
|
||||
/// It returns an SBValue, similar to FindValue() method, if find-and-watch
|
||||
/// operation succeeds. Otherwise, an invalid SBValue is returned.
|
||||
/// You can use LLDB_WATCH_TYPE_READ | LLDB_WATCH_TYPE_WRITE for 'rw' watch.
|
||||
lldb::SBValue
|
||||
WatchValue (const char *name, ValueType value_type, uint32_t watch_type);
|
||||
|
||||
/// Find and watch the location pointed to by a variable using the frame as
|
||||
/// the scope.
|
||||
/// It returns an SBValue, similar to FindValue() method, if find-and-watch
|
||||
/// operation succeeds. Otherwise, an invalid SBValue is returned.
|
||||
/// You can use LLDB_WATCH_TYPE_READ | LLDB_WATCH_TYPE_WRITE for 'rw' watch.
|
||||
lldb::SBValue
|
||||
WatchLocation (const char *name, ValueType value_type, uint32_t watch_type, size_t size);
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
#ifndef SWIG
|
||||
SBFrame (const lldb::StackFrameSP &lldb_object_sp);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
friend class SBValue;
|
||||
|
||||
private:
|
||||
friend class SBThread;
|
||||
friend class SBInstruction;
|
||||
friend class lldb_private::ScriptInterpreterPython;
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
lldb_private::StackFrame *
|
||||
operator->() const;
|
||||
|
||||
// Mimic shared pointer...
|
||||
lldb_private::StackFrame *
|
||||
get() const;
|
||||
|
||||
lldb::StackFrameSP &
|
||||
get_sp();
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
SetFrame (const lldb::StackFrameSP &lldb_object_sp);
|
||||
|
||||
lldb::StackFrameSP m_opaque_sp;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBFrame_h_
|
||||
@@ -1,93 +0,0 @@
|
||||
//===-- SBFunction.h --------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBFunction_h_
|
||||
#define LLDB_SBFunction_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBAddress.h"
|
||||
#include "lldb/API/SBInstructionList.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBFunction
|
||||
{
|
||||
public:
|
||||
|
||||
SBFunction ();
|
||||
|
||||
SBFunction (const lldb::SBFunction &rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBFunction &
|
||||
operator = (const lldb::SBFunction &rhs);
|
||||
#endif
|
||||
|
||||
|
||||
~SBFunction ();
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
const char *
|
||||
GetName() const;
|
||||
|
||||
const char *
|
||||
GetMangledName () const;
|
||||
|
||||
lldb::SBInstructionList
|
||||
GetInstructions (lldb::SBTarget target);
|
||||
|
||||
SBAddress
|
||||
GetStartAddress ();
|
||||
|
||||
SBAddress
|
||||
GetEndAddress ();
|
||||
|
||||
uint32_t
|
||||
GetPrologueByteSize ();
|
||||
|
||||
#ifndef SWIG
|
||||
bool
|
||||
operator == (const lldb::SBFunction &rhs) const;
|
||||
|
||||
bool
|
||||
operator != (const lldb::SBFunction &rhs) const;
|
||||
#endif
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
protected:
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
lldb_private::Function *
|
||||
get ();
|
||||
|
||||
void
|
||||
reset (lldb_private::Function *lldb_object_ptr);
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class SBAddress;
|
||||
friend class SBFrame;
|
||||
friend class SBSymbolContext;
|
||||
|
||||
SBFunction (lldb_private::Function *lldb_object_ptr);
|
||||
|
||||
|
||||
lldb_private::Function *m_opaque_ptr;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBFunction_h_
|
||||
@@ -1,54 +0,0 @@
|
||||
//===-- SBHostOS.h ----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBHostOS_h_
|
||||
#define LLDB_SBHostOS_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBFileSpec.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBHostOS
|
||||
{
|
||||
public:
|
||||
|
||||
static lldb::SBFileSpec
|
||||
GetProgramFileSpec ();
|
||||
|
||||
static void
|
||||
ThreadCreated (const char *name);
|
||||
|
||||
static lldb::thread_t
|
||||
ThreadCreate (const char *name,
|
||||
void *(*thread_function)(void *),
|
||||
void *thread_arg,
|
||||
lldb::SBError *err);
|
||||
|
||||
static bool
|
||||
ThreadCancel (lldb::thread_t thread,
|
||||
lldb::SBError *err);
|
||||
|
||||
static bool
|
||||
ThreadDetach (lldb::thread_t thread,
|
||||
lldb::SBError *err);
|
||||
static bool
|
||||
ThreadJoin (lldb::thread_t thread,
|
||||
void **result,
|
||||
lldb::SBError *err);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBHostOS_h_
|
||||
@@ -1,104 +0,0 @@
|
||||
//===-- SBInputReader.h -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBInputReader_h_
|
||||
#define LLDB_SBInputReader_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBInputReader
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t (*Callback) (void *baton,
|
||||
SBInputReader *reader,
|
||||
InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
SBInputReader ();
|
||||
|
||||
SBInputReader (const lldb::InputReaderSP &reader_sp);
|
||||
|
||||
SBInputReader (const lldb::SBInputReader &rhs);
|
||||
|
||||
~SBInputReader ();
|
||||
|
||||
|
||||
SBError
|
||||
Initialize (SBDebugger &debugger,
|
||||
Callback callback,
|
||||
void *callback_baton,
|
||||
lldb::InputReaderGranularity granularity,
|
||||
const char *end_token,
|
||||
const char *prompt,
|
||||
bool echo);
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBInputReader &
|
||||
operator = (const lldb::SBInputReader &rhs);
|
||||
#endif
|
||||
|
||||
bool
|
||||
IsActive () const;
|
||||
|
||||
bool
|
||||
IsDone () const;
|
||||
|
||||
void
|
||||
SetIsDone (bool value);
|
||||
|
||||
InputReaderGranularity
|
||||
GetGranularity ();
|
||||
|
||||
protected:
|
||||
friend class SBDebugger;
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
lldb_private::InputReader *
|
||||
operator->() const;
|
||||
|
||||
lldb::InputReaderSP &
|
||||
operator *();
|
||||
|
||||
const lldb::InputReaderSP &
|
||||
operator *() const;
|
||||
|
||||
lldb_private::InputReader *
|
||||
get() const;
|
||||
|
||||
lldb_private::InputReader &
|
||||
ref() const;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
private:
|
||||
|
||||
static size_t
|
||||
PrivateCallback (void *baton,
|
||||
lldb_private::InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
lldb::InputReaderSP m_opaque_sp;
|
||||
Callback m_callback_function;
|
||||
void *m_callback_baton;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBInputReader_h_
|
||||
@@ -1,93 +0,0 @@
|
||||
//===-- SBInstruction.h -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBInstruction_h_
|
||||
#define LLDB_SBInstruction_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBData.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// There's a lot to be fixed here, but need to wait for underlying insn implementation
|
||||
// to be revised & settle down first.
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBInstruction
|
||||
{
|
||||
public:
|
||||
|
||||
SBInstruction ();
|
||||
|
||||
SBInstruction (const SBInstruction &rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
const SBInstruction &
|
||||
operator = (const SBInstruction &rhs);
|
||||
#endif
|
||||
|
||||
~SBInstruction ();
|
||||
|
||||
bool
|
||||
IsValid();
|
||||
|
||||
SBAddress
|
||||
GetAddress();
|
||||
|
||||
const char *
|
||||
GetMnemonic (lldb::SBTarget target);
|
||||
|
||||
const char *
|
||||
GetOperands (lldb::SBTarget target);
|
||||
|
||||
const char *
|
||||
GetComment (lldb::SBTarget target);
|
||||
|
||||
lldb::SBData
|
||||
GetData (lldb::SBTarget target);
|
||||
|
||||
size_t
|
||||
GetByteSize ();
|
||||
|
||||
bool
|
||||
DoesBranch ();
|
||||
|
||||
void
|
||||
Print (FILE *out);
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
bool
|
||||
EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options);
|
||||
|
||||
bool
|
||||
DumpEmulation (const char * triple); // triple is to specify the architecture, e.g. 'armv6' or 'arm-apple-darwin'
|
||||
|
||||
bool
|
||||
TestEmulation (lldb::SBStream &output_stream, const char *test_file);
|
||||
|
||||
protected:
|
||||
friend class SBInstructionList;
|
||||
|
||||
SBInstruction (const lldb::InstructionSP &inst_sp);
|
||||
|
||||
void
|
||||
SetOpaque (const lldb::InstructionSP &inst_sp);
|
||||
|
||||
private:
|
||||
|
||||
lldb::InstructionSP m_opaque_sp;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBInstruction_h_
|
||||
@@ -1,72 +0,0 @@
|
||||
//===-- SBInstructionList.h -------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBInstructionList_h_
|
||||
#define LLDB_SBInstructionList_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBInstructionList
|
||||
{
|
||||
public:
|
||||
|
||||
SBInstructionList ();
|
||||
|
||||
SBInstructionList (const SBInstructionList &rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
const SBInstructionList &
|
||||
operator = (const SBInstructionList &rhs);
|
||||
#endif
|
||||
|
||||
~SBInstructionList ();
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
size_t
|
||||
GetSize ();
|
||||
|
||||
lldb::SBInstruction
|
||||
GetInstructionAtIndex (uint32_t idx);
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
void
|
||||
AppendInstruction (lldb::SBInstruction inst);
|
||||
|
||||
void
|
||||
Print (FILE *out);
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
bool
|
||||
DumpEmulationForAllInstructions (const char *triple);
|
||||
|
||||
protected:
|
||||
friend class SBFunction;
|
||||
friend class SBSymbol;
|
||||
|
||||
void
|
||||
SetDisassembler (const lldb::DisassemblerSP &opaque_sp);
|
||||
|
||||
private:
|
||||
lldb::DisassemblerSP m_opaque_sp;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBInstructionList_h_
|
||||
@@ -1,109 +0,0 @@
|
||||
//===-- SBLineEntry.h -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBLineEntry_h_
|
||||
#define LLDB_SBLineEntry_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBAddress.h"
|
||||
#include "lldb/API/SBFileSpec.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBLineEntry
|
||||
{
|
||||
public:
|
||||
|
||||
SBLineEntry ();
|
||||
|
||||
SBLineEntry (const lldb::SBLineEntry &rhs);
|
||||
|
||||
~SBLineEntry ();
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBLineEntry &
|
||||
operator = (const lldb::SBLineEntry &rhs);
|
||||
#endif
|
||||
|
||||
lldb::SBAddress
|
||||
GetStartAddress () const;
|
||||
|
||||
lldb::SBAddress
|
||||
GetEndAddress () const;
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
lldb::SBFileSpec
|
||||
GetFileSpec () const;
|
||||
|
||||
uint32_t
|
||||
GetLine () const;
|
||||
|
||||
uint32_t
|
||||
GetColumn () const;
|
||||
|
||||
void
|
||||
SetFileSpec (lldb::SBFileSpec filespec);
|
||||
|
||||
void
|
||||
SetLine (uint32_t line);
|
||||
|
||||
void
|
||||
SetColumn (uint32_t column);
|
||||
|
||||
#ifndef SWIG
|
||||
bool
|
||||
operator == (const lldb::SBLineEntry &rhs) const;
|
||||
|
||||
bool
|
||||
operator != (const lldb::SBLineEntry &rhs) const;
|
||||
|
||||
#endif
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
protected:
|
||||
|
||||
lldb_private::LineEntry *
|
||||
get ();
|
||||
|
||||
private:
|
||||
friend class SBAddress;
|
||||
friend class SBCompileUnit;
|
||||
friend class SBFrame;
|
||||
friend class SBSymbolContext;
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
const lldb_private::LineEntry *
|
||||
operator->() const;
|
||||
|
||||
lldb_private::LineEntry &
|
||||
ref();
|
||||
|
||||
const lldb_private::LineEntry &
|
||||
ref() const;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
SBLineEntry (const lldb_private::LineEntry *lldb_object_ptr);
|
||||
|
||||
void
|
||||
SetLineEntry (const lldb_private::LineEntry &lldb_object_ref);
|
||||
|
||||
std::auto_ptr<lldb_private::LineEntry> m_opaque_ap;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBLineEntry_h_
|
||||
@@ -1,131 +0,0 @@
|
||||
//===-- SBListener.h --------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBListener_h_
|
||||
#define LLDB_SBListener_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBListener
|
||||
{
|
||||
public:
|
||||
SBListener ();
|
||||
|
||||
SBListener (const char *name);
|
||||
|
||||
SBListener (const SBListener &rhs);
|
||||
|
||||
~SBListener ();
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBListener &
|
||||
operator = (const lldb::SBListener &rhs);
|
||||
#endif
|
||||
|
||||
void
|
||||
AddEvent (const lldb::SBEvent &event);
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
uint32_t
|
||||
StartListeningForEvents (const lldb::SBBroadcaster& broadcaster,
|
||||
uint32_t event_mask);
|
||||
|
||||
bool
|
||||
StopListeningForEvents (const lldb::SBBroadcaster& broadcaster,
|
||||
uint32_t event_mask);
|
||||
|
||||
// Returns true if an event was recieved, false if we timed out.
|
||||
bool
|
||||
WaitForEvent (uint32_t num_seconds,
|
||||
lldb::SBEvent &event);
|
||||
|
||||
bool
|
||||
WaitForEventForBroadcaster (uint32_t num_seconds,
|
||||
const lldb::SBBroadcaster &broadcaster,
|
||||
lldb::SBEvent &sb_event);
|
||||
|
||||
bool
|
||||
WaitForEventForBroadcasterWithType (uint32_t num_seconds,
|
||||
const lldb::SBBroadcaster &broadcaster,
|
||||
uint32_t event_type_mask,
|
||||
lldb::SBEvent &sb_event);
|
||||
|
||||
bool
|
||||
PeekAtNextEvent (lldb::SBEvent &sb_event);
|
||||
|
||||
bool
|
||||
PeekAtNextEventForBroadcaster (const lldb::SBBroadcaster &broadcaster,
|
||||
lldb::SBEvent &sb_event);
|
||||
|
||||
bool
|
||||
PeekAtNextEventForBroadcasterWithType (const lldb::SBBroadcaster &broadcaster,
|
||||
uint32_t event_type_mask,
|
||||
lldb::SBEvent &sb_event);
|
||||
|
||||
bool
|
||||
GetNextEvent (lldb::SBEvent &sb_event);
|
||||
|
||||
bool
|
||||
GetNextEventForBroadcaster (const lldb::SBBroadcaster &broadcaster,
|
||||
lldb::SBEvent &sb_event);
|
||||
|
||||
bool
|
||||
GetNextEventForBroadcasterWithType (const lldb::SBBroadcaster &broadcaster,
|
||||
uint32_t event_type_mask,
|
||||
lldb::SBEvent &sb_event);
|
||||
|
||||
bool
|
||||
HandleBroadcastEvent (const lldb::SBEvent &event);
|
||||
|
||||
protected:
|
||||
friend class SBBroadcaster;
|
||||
friend class SBCommandInterpreter;
|
||||
friend class SBDebugger;
|
||||
friend class SBTarget;
|
||||
|
||||
SBListener (lldb_private::Listener &listener);
|
||||
|
||||
private:
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
lldb_private::Listener *
|
||||
operator->() const;
|
||||
|
||||
lldb_private::Listener *
|
||||
get() const;
|
||||
|
||||
lldb_private::Listener &
|
||||
ref() const;
|
||||
|
||||
lldb_private::Listener &
|
||||
operator *();
|
||||
|
||||
const lldb_private::Listener &
|
||||
operator *() const;
|
||||
|
||||
void
|
||||
reset(lldb_private::Listener *listener, bool transfer_ownership);
|
||||
|
||||
#endif
|
||||
|
||||
lldb::ListenerSP m_opaque_sp;
|
||||
lldb_private::Listener *m_opaque_ptr;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBListener_h_
|
||||
@@ -1,211 +0,0 @@
|
||||
//===-- SBModule.h ----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBModule_h_
|
||||
#define LLDB_SBModule_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBError.h"
|
||||
#include "lldb/API/SBSection.h"
|
||||
#include "lldb/API/SBSymbolContext.h"
|
||||
#include "lldb/API/SBValueList.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBModule
|
||||
{
|
||||
public:
|
||||
|
||||
SBModule ();
|
||||
|
||||
SBModule (const SBModule &rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
const SBModule &
|
||||
operator = (const SBModule &rhs);
|
||||
#endif
|
||||
|
||||
~SBModule ();
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get const accessor for the module file specification.
|
||||
///
|
||||
/// This function returns the file for the module on the host system
|
||||
/// that is running LLDB. This can differ from the path on the
|
||||
/// platform since we might be doing remote debugging.
|
||||
///
|
||||
/// @return
|
||||
/// A const reference to the file specification object.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBFileSpec
|
||||
GetFileSpec () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get accessor for the module platform file specification.
|
||||
///
|
||||
/// Platform file refers to the path of the module as it is known on
|
||||
/// the remote system on which it is being debugged. For local
|
||||
/// debugging this is always the same as Module::GetFileSpec(). But
|
||||
/// remote debugging might mention a file '/usr/lib/liba.dylib'
|
||||
/// which might be locally downloaded and cached. In this case the
|
||||
/// platform file could be something like:
|
||||
/// '/tmp/lldb/platform-cache/remote.host.computer/usr/lib/liba.dylib'
|
||||
/// The file could also be cached in a local developer kit directory.
|
||||
///
|
||||
/// @return
|
||||
/// A const reference to the file specification object.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBFileSpec
|
||||
GetPlatformFileSpec () const;
|
||||
|
||||
bool
|
||||
SetPlatformFileSpec (const lldb::SBFileSpec &platform_file);
|
||||
|
||||
#ifndef SWIG
|
||||
const uint8_t *
|
||||
GetUUIDBytes () const;
|
||||
#endif
|
||||
|
||||
const char *
|
||||
GetUUIDString () const;
|
||||
|
||||
#ifndef SWIG
|
||||
bool
|
||||
operator == (const lldb::SBModule &rhs) const;
|
||||
|
||||
bool
|
||||
operator != (const lldb::SBModule &rhs) const;
|
||||
|
||||
#endif
|
||||
lldb::SBSection
|
||||
FindSection (const char *sect_name);
|
||||
|
||||
lldb::SBAddress
|
||||
ResolveFileAddress (lldb::addr_t vm_addr);
|
||||
|
||||
lldb::SBSymbolContext
|
||||
ResolveSymbolContextForAddress (const lldb::SBAddress& addr,
|
||||
uint32_t resolve_scope);
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
size_t
|
||||
GetNumSymbols ();
|
||||
|
||||
lldb::SBSymbol
|
||||
GetSymbolAtIndex (size_t idx);
|
||||
|
||||
size_t
|
||||
GetNumSections ();
|
||||
|
||||
lldb::SBSection
|
||||
GetSectionAtIndex (size_t idx);
|
||||
//------------------------------------------------------------------
|
||||
/// Find functions by name.
|
||||
///
|
||||
/// @param[in] name
|
||||
/// The name of the function we are looking for.
|
||||
///
|
||||
/// @param[in] name_type_mask
|
||||
/// A logical OR of one or more FunctionNameType enum bits that
|
||||
/// indicate what kind of names should be used when doing the
|
||||
/// lookup. Bits include fully qualified names, base names,
|
||||
/// C++ methods, or ObjC selectors.
|
||||
/// See FunctionNameType for more details.
|
||||
///
|
||||
/// @param[in] append
|
||||
/// If true, any matches will be appended to \a sc_list, else
|
||||
/// matches replace the contents of \a sc_list.
|
||||
///
|
||||
/// @param[out] sc_list
|
||||
/// A symbol context list that gets filled in with all of the
|
||||
/// matches.
|
||||
///
|
||||
/// @return
|
||||
/// The number of matches added to \a sc_list.
|
||||
//------------------------------------------------------------------
|
||||
uint32_t
|
||||
FindFunctions (const char *name,
|
||||
uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
|
||||
bool append,
|
||||
lldb::SBSymbolContextList& sc_list);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Find global and static variables by name.
|
||||
///
|
||||
/// @param[in] target
|
||||
/// A valid SBTarget instance representing the debuggee.
|
||||
///
|
||||
/// @param[in] name
|
||||
/// The name of the global or static variable we are looking
|
||||
/// for.
|
||||
///
|
||||
/// @param[in] max_matches
|
||||
/// Allow the number of matches to be limited to \a max_matches.
|
||||
///
|
||||
/// @return
|
||||
/// A list of matched variables in an SBValueList.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBValueList
|
||||
FindGlobalVariables (lldb::SBTarget &target,
|
||||
const char *name,
|
||||
uint32_t max_matches);
|
||||
|
||||
lldb::SBType
|
||||
FindFirstType (const char* name);
|
||||
|
||||
lldb::SBTypeList
|
||||
FindTypes (const char* type);
|
||||
|
||||
private:
|
||||
friend class SBAddress;
|
||||
friend class SBFrame;
|
||||
friend class SBSection;
|
||||
friend class SBSymbolContext;
|
||||
friend class SBTarget;
|
||||
|
||||
explicit SBModule (const lldb::ModuleSP& module_sp);
|
||||
|
||||
void
|
||||
SetModule (const lldb::ModuleSP& module_sp);
|
||||
#ifndef SWIG
|
||||
|
||||
lldb::ModuleSP &
|
||||
operator *();
|
||||
|
||||
|
||||
lldb_private::Module *
|
||||
operator ->();
|
||||
|
||||
const lldb_private::Module *
|
||||
operator ->() const;
|
||||
|
||||
lldb_private::Module *
|
||||
get();
|
||||
|
||||
const lldb_private::Module *
|
||||
get() const;
|
||||
|
||||
const lldb::ModuleSP &
|
||||
get_sp() const;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
lldb::ModuleSP m_opaque_sp;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBModule_h_
|
||||
@@ -1,213 +0,0 @@
|
||||
//===-- SBProcess.h ---------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBProcess_h_
|
||||
#define LLDB_SBProcess_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBError.h"
|
||||
#include "lldb/API/SBTarget.h"
|
||||
#include <stdio.h>
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBEvent;
|
||||
|
||||
class SBProcess
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------
|
||||
/// Broadcaster event bits definitions.
|
||||
//------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
eBroadcastBitStateChanged = (1 << 0),
|
||||
eBroadcastBitInterrupt = (1 << 1),
|
||||
eBroadcastBitSTDOUT = (1 << 2),
|
||||
eBroadcastBitSTDERR = (1 << 3)
|
||||
};
|
||||
|
||||
SBProcess ();
|
||||
|
||||
SBProcess (const lldb::SBProcess& rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBProcess&
|
||||
operator = (const lldb::SBProcess& rhs);
|
||||
#endif
|
||||
|
||||
~SBProcess();
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
lldb::SBTarget
|
||||
GetTarget() const;
|
||||
|
||||
lldb::ByteOrder
|
||||
GetByteOrder() const;
|
||||
|
||||
size_t
|
||||
PutSTDIN (const char *src, size_t src_len);
|
||||
|
||||
size_t
|
||||
GetSTDOUT (char *dst, size_t dst_len) const;
|
||||
|
||||
size_t
|
||||
GetSTDERR (char *dst, size_t dst_len) const;
|
||||
|
||||
void
|
||||
ReportEventState (const lldb::SBEvent &event, FILE *out) const;
|
||||
|
||||
void
|
||||
AppendEventStateReport (const lldb::SBEvent &event, lldb::SBCommandReturnObject &result);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Remote connection related functions. These will fail if the
|
||||
/// process is not in eStateConnected. They are intended for use
|
||||
/// when connecting to an externally managed debugserver instance.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
RemoteAttachToProcessWithID (lldb::pid_t pid,
|
||||
lldb::SBError& error);
|
||||
|
||||
bool
|
||||
RemoteLaunch (char const **argv,
|
||||
char const **envp,
|
||||
const char *stdin_path,
|
||||
const char *stdout_path,
|
||||
const char *stderr_path,
|
||||
const char *working_directory,
|
||||
uint32_t launch_flags,
|
||||
bool stop_at_entry,
|
||||
lldb::SBError& error);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Thread related functions
|
||||
//------------------------------------------------------------------
|
||||
uint32_t
|
||||
GetNumThreads ();
|
||||
|
||||
lldb::SBThread
|
||||
GetThreadAtIndex (size_t index);
|
||||
|
||||
lldb::SBThread
|
||||
GetThreadByID (lldb::tid_t sb_thread_id);
|
||||
|
||||
lldb::SBThread
|
||||
GetSelectedThread () const;
|
||||
|
||||
bool
|
||||
SetSelectedThread (const lldb::SBThread &thread);
|
||||
|
||||
bool
|
||||
SetSelectedThreadByID (uint32_t tid);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Stepping related functions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
lldb::StateType
|
||||
GetState ();
|
||||
|
||||
int
|
||||
GetExitStatus ();
|
||||
|
||||
const char *
|
||||
GetExitDescription ();
|
||||
|
||||
lldb::pid_t
|
||||
GetProcessID ();
|
||||
|
||||
uint32_t
|
||||
GetAddressByteSize() const;
|
||||
|
||||
lldb::SBError
|
||||
Destroy ();
|
||||
|
||||
lldb::SBError
|
||||
Continue ();
|
||||
|
||||
lldb::SBError
|
||||
Stop ();
|
||||
|
||||
lldb::SBError
|
||||
Kill ();
|
||||
|
||||
lldb::SBError
|
||||
Detach ();
|
||||
|
||||
lldb::SBError
|
||||
Signal (int signal);
|
||||
|
||||
size_t
|
||||
ReadMemory (addr_t addr, void *buf, size_t size, lldb::SBError &error);
|
||||
|
||||
size_t
|
||||
WriteMemory (addr_t addr, const void *buf, size_t size, lldb::SBError &error);
|
||||
|
||||
// Events
|
||||
static lldb::StateType
|
||||
GetStateFromEvent (const lldb::SBEvent &event);
|
||||
|
||||
static bool
|
||||
GetRestartedFromEvent (const lldb::SBEvent &event);
|
||||
|
||||
static lldb::SBProcess
|
||||
GetProcessFromEvent (const lldb::SBEvent &event);
|
||||
|
||||
lldb::SBBroadcaster
|
||||
GetBroadcaster () const;
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
uint32_t
|
||||
LoadImage (lldb::SBFileSpec &image_spec, lldb::SBError &error);
|
||||
|
||||
lldb::SBError
|
||||
UnloadImage (uint32_t image_token);
|
||||
|
||||
protected:
|
||||
friend class SBAddress;
|
||||
friend class SBBreakpoint;
|
||||
friend class SBBreakpointLocation;
|
||||
friend class SBCommandInterpreter;
|
||||
friend class SBDebugger;
|
||||
friend class SBFunction;
|
||||
friend class SBTarget;
|
||||
friend class SBThread;
|
||||
friend class SBValue;
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
lldb_private::Process *
|
||||
operator->() const;
|
||||
|
||||
// Mimic shared pointer...
|
||||
lldb_private::Process *
|
||||
get() const;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
SBProcess (const lldb::ProcessSP &process_sp);
|
||||
|
||||
void
|
||||
SetProcess (const lldb::ProcessSP &process_sp);
|
||||
|
||||
lldb::ProcessSP m_opaque_sp;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBProcess_h_
|
||||
@@ -1,103 +0,0 @@
|
||||
//===-- SBSection.h ---------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBSection_h_
|
||||
#define LLDB_SBSection_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBData.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBSection
|
||||
{
|
||||
public:
|
||||
|
||||
SBSection ();
|
||||
|
||||
SBSection (const lldb::SBSection &rhs);
|
||||
|
||||
~SBSection ();
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBSection &
|
||||
operator = (const lldb::SBSection &rhs);
|
||||
#endif
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
const char *
|
||||
GetName ();
|
||||
|
||||
lldb::SBSection
|
||||
FindSubSection (const char *sect_name);
|
||||
|
||||
size_t
|
||||
GetNumSubSections ();
|
||||
|
||||
lldb::SBSection
|
||||
GetSubSectionAtIndex (size_t idx);
|
||||
|
||||
lldb::addr_t
|
||||
GetFileAddress ();
|
||||
|
||||
lldb::addr_t
|
||||
GetByteSize ();
|
||||
|
||||
uint64_t
|
||||
GetFileOffset ();
|
||||
|
||||
uint64_t
|
||||
GetFileByteSize ();
|
||||
|
||||
lldb::SBData
|
||||
GetSectionData ();
|
||||
|
||||
lldb::SBData
|
||||
GetSectionData (uint64_t offset,
|
||||
uint64_t size);
|
||||
|
||||
SectionType
|
||||
GetSectionType ();
|
||||
|
||||
#ifndef SWIG
|
||||
bool
|
||||
operator == (const lldb::SBSection &rhs);
|
||||
|
||||
bool
|
||||
operator != (const lldb::SBSection &rhs);
|
||||
|
||||
#endif
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
private:
|
||||
|
||||
#ifndef SWIG
|
||||
friend class SBAddress;
|
||||
friend class SBModule;
|
||||
friend class SBTarget;
|
||||
|
||||
SBSection (const lldb_private::Section *section);
|
||||
|
||||
const lldb_private::Section *
|
||||
GetSection();
|
||||
|
||||
void
|
||||
SetSection (const lldb_private::Section *section);
|
||||
#endif
|
||||
|
||||
std::auto_ptr<lldb_private::SectionImpl> m_opaque_ap;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBSection_h_
|
||||
@@ -1,55 +0,0 @@
|
||||
//===-- SBSourceManager.h ---------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBSourceManager_h_
|
||||
#define LLDB_SBSourceManager_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBSourceManager
|
||||
{
|
||||
public:
|
||||
SBSourceManager (const SBDebugger &debugger);
|
||||
SBSourceManager (const SBTarget &target);
|
||||
SBSourceManager (const SBSourceManager &rhs);
|
||||
|
||||
~SBSourceManager();
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBSourceManager &
|
||||
operator = (const lldb::SBSourceManager &rhs);
|
||||
#endif
|
||||
|
||||
size_t
|
||||
DisplaySourceLinesWithLineNumbers (const lldb::SBFileSpec &file,
|
||||
uint32_t line,
|
||||
uint32_t context_before,
|
||||
uint32_t context_after,
|
||||
const char* current_line_cstr,
|
||||
lldb::SBStream &s);
|
||||
|
||||
|
||||
protected:
|
||||
friend class SBCommandInterpreter;
|
||||
friend class SBDebugger;
|
||||
|
||||
SBSourceManager(lldb_private::SourceManager *source_manager);
|
||||
|
||||
private:
|
||||
|
||||
std::auto_ptr<lldb_private::SourceManagerImpl> m_opaque_ap;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBSourceManager_h_
|
||||
@@ -1,104 +0,0 @@
|
||||
//===-- SBStream.h ----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBStream_h_
|
||||
#define LLDB_SBStream_h_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBStream
|
||||
{
|
||||
public:
|
||||
|
||||
SBStream ();
|
||||
|
||||
~SBStream ();
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
// If this stream is not redirected to a file, it will maintain a local
|
||||
// cache for the stream data which can be accessed using this accessor.
|
||||
const char *
|
||||
GetData ();
|
||||
|
||||
// If this stream is not redirected to a file, it will maintain a local
|
||||
// cache for the stream output whose length can be accessed using this
|
||||
// accessor.
|
||||
size_t
|
||||
GetSize();
|
||||
|
||||
void
|
||||
Printf (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
|
||||
void
|
||||
RedirectToFile (const char *path, bool append);
|
||||
|
||||
void
|
||||
RedirectToFileHandle (FILE *fh, bool transfer_fh_ownership);
|
||||
|
||||
void
|
||||
RedirectToFileDescriptor (int fd, bool transfer_fh_ownership);
|
||||
|
||||
// If the stream is redirected to a file, forget about the file and if
|
||||
// ownership of the file was transfered to this object, close the file.
|
||||
// If the stream is backed by a local cache, clear this cache.
|
||||
void
|
||||
Clear ();
|
||||
|
||||
protected:
|
||||
friend class SBAddress;
|
||||
friend class SBBlock;
|
||||
friend class SBBreakpoint;
|
||||
friend class SBBreakpointLocation;
|
||||
friend class SBCommandReturnObject;
|
||||
friend class SBCompileUnit;
|
||||
friend class SBData;
|
||||
friend class SBEvent;
|
||||
friend class SBFrame;
|
||||
friend class SBFunction;
|
||||
friend class SBInstruction;
|
||||
friend class SBInstructionList;
|
||||
friend class SBModule;
|
||||
friend class SBSection;
|
||||
friend class SBSourceManager;
|
||||
friend class SBSymbol;
|
||||
friend class SBSymbolContext;
|
||||
friend class SBTarget;
|
||||
friend class SBThread;
|
||||
friend class SBValue;
|
||||
friend class SBWatchpoint;
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
lldb_private::Stream *
|
||||
operator->();
|
||||
|
||||
lldb_private::Stream *
|
||||
get();
|
||||
|
||||
lldb_private::Stream &
|
||||
ref();
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (SBStream);
|
||||
std::auto_ptr<lldb_private::Stream> m_opaque_ap;
|
||||
bool m_is_file;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBStream_h_
|
||||
@@ -1,76 +0,0 @@
|
||||
//===-- SBStringList.h ------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBStringList_h_
|
||||
#define LLDB_SBStringList_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBStringList
|
||||
{
|
||||
public:
|
||||
|
||||
SBStringList ();
|
||||
|
||||
SBStringList (const lldb::SBStringList &rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
const SBStringList &
|
||||
operator = (const SBStringList &rhs);
|
||||
#endif
|
||||
|
||||
~SBStringList ();
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
void
|
||||
AppendString (const char *str);
|
||||
|
||||
void
|
||||
AppendList (const char **strv, int strc);
|
||||
|
||||
void
|
||||
AppendList (const lldb::SBStringList &strings);
|
||||
|
||||
uint32_t
|
||||
GetSize () const;
|
||||
|
||||
const char *
|
||||
GetStringAtIndex (size_t idx);
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
protected:
|
||||
friend class SBCommandInterpreter;
|
||||
|
||||
SBStringList (const lldb_private::StringList *lldb_strings);
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
const lldb_private::StringList *
|
||||
operator->() const;
|
||||
|
||||
const lldb_private::StringList &
|
||||
operator*() const;
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
std::auto_ptr<lldb_private::StringList> m_opaque_ap;
|
||||
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBStringList_h_
|
||||
@@ -1,98 +0,0 @@
|
||||
//===-- SBSymbol.h ----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBSymbol_h_
|
||||
#define LLDB_SBSymbol_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBAddress.h"
|
||||
#include "lldb/API/SBInstructionList.h"
|
||||
#include "lldb/API/SBTarget.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBSymbol
|
||||
{
|
||||
public:
|
||||
|
||||
SBSymbol ();
|
||||
|
||||
~SBSymbol ();
|
||||
|
||||
SBSymbol (const lldb::SBSymbol &rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBSymbol &
|
||||
operator = (const lldb::SBSymbol &rhs);
|
||||
#endif
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
|
||||
const char *
|
||||
GetName() const;
|
||||
|
||||
const char *
|
||||
GetMangledName () const;
|
||||
|
||||
lldb::SBInstructionList
|
||||
GetInstructions (lldb::SBTarget target);
|
||||
|
||||
SBAddress
|
||||
GetStartAddress ();
|
||||
|
||||
SBAddress
|
||||
GetEndAddress ();
|
||||
|
||||
uint32_t
|
||||
GetPrologueByteSize ();
|
||||
|
||||
SymbolType
|
||||
GetType ();
|
||||
|
||||
#ifndef SWIG
|
||||
bool
|
||||
operator == (const lldb::SBSymbol &rhs) const;
|
||||
|
||||
bool
|
||||
operator != (const lldb::SBSymbol &rhs) const;
|
||||
#endif
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
protected:
|
||||
|
||||
#ifndef SWIG
|
||||
lldb_private::Symbol *
|
||||
get ();
|
||||
|
||||
void
|
||||
reset (lldb_private::Symbol *);
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class SBAddress;
|
||||
friend class SBFrame;
|
||||
friend class SBModule;
|
||||
friend class SBSymbolContext;
|
||||
|
||||
SBSymbol (lldb_private::Symbol *lldb_object_ptr);
|
||||
|
||||
void
|
||||
SetSymbol (lldb_private::Symbol *lldb_object_ptr);
|
||||
|
||||
lldb_private::Symbol *m_opaque_ptr;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBSymbol_h_
|
||||
@@ -1,100 +0,0 @@
|
||||
//===-- SBSymbolContext.h ---------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBSymbolContext_h_
|
||||
#define LLDB_SBSymbolContext_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBBlock.h"
|
||||
#include "lldb/API/SBCompileUnit.h"
|
||||
#include "lldb/API/SBFunction.h"
|
||||
#include "lldb/API/SBLineEntry.h"
|
||||
#include "lldb/API/SBModule.h"
|
||||
#include "lldb/API/SBSymbol.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBSymbolContext
|
||||
{
|
||||
public:
|
||||
SBSymbolContext ();
|
||||
|
||||
SBSymbolContext (const lldb::SBSymbolContext& rhs);
|
||||
|
||||
~SBSymbolContext ();
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBSymbolContext &
|
||||
operator = (const lldb::SBSymbolContext &rhs);
|
||||
#endif
|
||||
|
||||
lldb::SBModule GetModule ();
|
||||
lldb::SBCompileUnit GetCompileUnit ();
|
||||
lldb::SBFunction GetFunction ();
|
||||
lldb::SBBlock GetBlock ();
|
||||
lldb::SBLineEntry GetLineEntry ();
|
||||
lldb::SBSymbol GetSymbol ();
|
||||
|
||||
void SetModule (lldb::SBModule module);
|
||||
void SetCompileUnit (lldb::SBCompileUnit compile_unit);
|
||||
void SetFunction (lldb::SBFunction function);
|
||||
void SetBlock (lldb::SBBlock block);
|
||||
void SetLineEntry (lldb::SBLineEntry line_entry);
|
||||
void SetSymbol (lldb::SBSymbol symbol);
|
||||
|
||||
SBSymbolContext
|
||||
GetParentOfInlinedScope (const SBAddress &curr_frame_pc,
|
||||
SBAddress &parent_frame_addr) const;
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
protected:
|
||||
friend class SBAddress;
|
||||
friend class SBFrame;
|
||||
friend class SBModule;
|
||||
friend class SBThread;
|
||||
friend class SBTarget;
|
||||
friend class SBSymbolContextList;
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
lldb_private::SymbolContext*
|
||||
operator->() const;
|
||||
|
||||
lldb_private::SymbolContext&
|
||||
operator*();
|
||||
|
||||
lldb_private::SymbolContext&
|
||||
ref();
|
||||
|
||||
const lldb_private::SymbolContext&
|
||||
operator*() const;
|
||||
|
||||
#endif
|
||||
|
||||
lldb_private::SymbolContext *
|
||||
get() const;
|
||||
|
||||
SBSymbolContext (const lldb_private::SymbolContext *sc_ptr);
|
||||
|
||||
void
|
||||
SetSymbolContext (const lldb_private::SymbolContext *sc_ptr);
|
||||
|
||||
private:
|
||||
std::auto_ptr<lldb_private::SymbolContext> m_opaque_ap;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBSymbolContext_h_
|
||||
@@ -1,66 +0,0 @@
|
||||
//===-- SBSymbolContextList.h -----------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBSymbolContextList_h_
|
||||
#define LLDB_SBSymbolContextList_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBSymbolContext.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBSymbolContextList
|
||||
{
|
||||
public:
|
||||
SBSymbolContextList ();
|
||||
|
||||
SBSymbolContextList (const lldb::SBSymbolContextList& rhs);
|
||||
|
||||
~SBSymbolContextList ();
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBSymbolContextList &
|
||||
operator = (const lldb::SBSymbolContextList &rhs);
|
||||
#endif
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
uint32_t
|
||||
GetSize() const;
|
||||
|
||||
SBSymbolContext
|
||||
GetContextAtIndex (uint32_t idx);
|
||||
|
||||
void
|
||||
Clear();
|
||||
|
||||
protected:
|
||||
|
||||
friend class SBModule;
|
||||
friend class SBTarget;
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
lldb_private::SymbolContextList*
|
||||
operator->() const;
|
||||
|
||||
lldb_private::SymbolContextList&
|
||||
operator*() const;
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
std::auto_ptr<lldb_private::SymbolContextList> m_opaque_ap;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBSymbolContextList_h_
|
||||
@@ -1,547 +0,0 @@
|
||||
//===-- SBTarget.h ----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBTarget_h_
|
||||
#define LLDB_SBTarget_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBAddress.h"
|
||||
#include "lldb/API/SBBroadcaster.h"
|
||||
#include "lldb/API/SBFileSpec.h"
|
||||
#include "lldb/API/SBFileSpecList.h"
|
||||
#include "lldb/API/SBType.h"
|
||||
#include "lldb/API/SBWatchpoint.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBBreakpoint;
|
||||
|
||||
class SBTarget
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------
|
||||
// Broadcaster bits.
|
||||
//------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
eBroadcastBitBreakpointChanged = (1 << 0),
|
||||
eBroadcastBitModulesLoaded = (1 << 1),
|
||||
eBroadcastBitModulesUnloaded = (1 << 2)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Constructors
|
||||
//------------------------------------------------------------------
|
||||
SBTarget ();
|
||||
|
||||
SBTarget (const lldb::SBTarget& rhs);
|
||||
|
||||
#ifndef SWIG
|
||||
const lldb::SBTarget&
|
||||
operator = (const lldb::SBTarget& rhs);
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Destructor
|
||||
//------------------------------------------------------------------
|
||||
~SBTarget();
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
lldb::SBProcess
|
||||
GetProcess ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Launch a new process.
|
||||
///
|
||||
/// Launch a new process by spawning a new process using the
|
||||
/// target object's executable module's file as the file to launch.
|
||||
/// Arguments are given in \a argv, and the environment variables
|
||||
/// are in \a envp. Standard input and output files can be
|
||||
/// optionally re-directed to \a stdin_path, \a stdout_path, and
|
||||
/// \a stderr_path.
|
||||
///
|
||||
/// @param[in] listener
|
||||
/// An optional listener that will receive all process events.
|
||||
/// If \a listener is valid then \a listener will listen to all
|
||||
/// process events. If not valid, then this target's debugger
|
||||
/// (SBTarget::GetDebugger()) will listen to all process events.
|
||||
///
|
||||
/// @param[in] argv
|
||||
/// The argument array.
|
||||
///
|
||||
/// @param[in] envp
|
||||
/// The environment array.
|
||||
///
|
||||
/// @param[in] launch_flags
|
||||
/// Flags to modify the launch (@see lldb::LaunchFlags)
|
||||
///
|
||||
/// @param[in] stdin_path
|
||||
/// The path to use when re-directing the STDIN of the new
|
||||
/// process. If all stdXX_path arguments are NULL, a pseudo
|
||||
/// terminal will be used.
|
||||
///
|
||||
/// @param[in] stdout_path
|
||||
/// The path to use when re-directing the STDOUT of the new
|
||||
/// process. If all stdXX_path arguments are NULL, a pseudo
|
||||
/// terminal will be used.
|
||||
///
|
||||
/// @param[in] stderr_path
|
||||
/// The path to use when re-directing the STDERR of the new
|
||||
/// process. If all stdXX_path arguments are NULL, a pseudo
|
||||
/// terminal will be used.
|
||||
///
|
||||
/// @param[in] working_directory
|
||||
/// The working directory to have the child process run in
|
||||
///
|
||||
/// @param[in] launch_flags
|
||||
/// Some launch options specified by logical OR'ing
|
||||
/// lldb::LaunchFlags enumeration values together.
|
||||
///
|
||||
/// @param[in] stop_at_endtry
|
||||
/// If false do not stop the inferior at the entry point.
|
||||
///
|
||||
/// @param[out]
|
||||
/// An error object. Contains the reason if there is some failure.
|
||||
///
|
||||
/// @return
|
||||
/// A process object for the newly created process.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBProcess
|
||||
Launch (SBListener &listener,
|
||||
char const **argv,
|
||||
char const **envp,
|
||||
const char *stdin_path,
|
||||
const char *stdout_path,
|
||||
const char *stderr_path,
|
||||
const char *working_directory,
|
||||
uint32_t launch_flags, // See LaunchFlags
|
||||
bool stop_at_entry,
|
||||
lldb::SBError& error);
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Launch a new process with sensible defaults.
|
||||
///
|
||||
/// @param[in] argv
|
||||
/// The argument array.
|
||||
///
|
||||
/// @param[in] envp
|
||||
/// The environment array.
|
||||
///
|
||||
/// @param[in] working_directory
|
||||
/// The working directory to have the child process run in
|
||||
///
|
||||
/// Default: listener
|
||||
/// Set to the target's debugger (SBTarget::GetDebugger())
|
||||
///
|
||||
/// Default: launch_flags
|
||||
/// Empty launch flags
|
||||
///
|
||||
/// Default: stdin_path
|
||||
/// Default: stdout_path
|
||||
/// Default: stderr_path
|
||||
/// A pseudo terminal will be used.
|
||||
///
|
||||
/// @return
|
||||
/// A process object for the newly created process.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBProcess
|
||||
LaunchSimple (const char **argv,
|
||||
const char **envp,
|
||||
const char *working_directory);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Attach to process with pid.
|
||||
///
|
||||
/// @param[in] listener
|
||||
/// An optional listener that will receive all process events.
|
||||
/// If \a listener is valid then \a listener will listen to all
|
||||
/// process events. If not valid, then this target's debugger
|
||||
/// (SBTarget::GetDebugger()) will listen to all process events.
|
||||
///
|
||||
/// @param[in] pid
|
||||
/// The process ID to attach to.
|
||||
///
|
||||
/// @param[out]
|
||||
/// An error explaining what went wrong if attach fails.
|
||||
///
|
||||
/// @return
|
||||
/// A process object for the attached process.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBProcess
|
||||
AttachToProcessWithID (SBListener &listener,
|
||||
lldb::pid_t pid,
|
||||
lldb::SBError& error);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Attach to process with name.
|
||||
///
|
||||
/// @param[in] listener
|
||||
/// An optional listener that will receive all process events.
|
||||
/// If \a listener is valid then \a listener will listen to all
|
||||
/// process events. If not valid, then this target's debugger
|
||||
/// (SBTarget::GetDebugger()) will listen to all process events.
|
||||
///
|
||||
/// @param[in] name
|
||||
/// Basename of process to attach to.
|
||||
///
|
||||
/// @param[in] wait_for
|
||||
/// If true wait for a new instance of 'name' to be launched.
|
||||
///
|
||||
/// @param[out]
|
||||
/// An error explaining what went wrong if attach fails.
|
||||
///
|
||||
/// @return
|
||||
/// A process object for the attached process.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBProcess
|
||||
AttachToProcessWithName (SBListener &listener,
|
||||
const char *name,
|
||||
bool wait_for,
|
||||
lldb::SBError& error);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Connect to a remote debug server with url.
|
||||
///
|
||||
/// @param[in] listener
|
||||
/// An optional listener that will receive all process events.
|
||||
/// If \a listener is valid then \a listener will listen to all
|
||||
/// process events. If not valid, then this target's debugger
|
||||
/// (SBTarget::GetDebugger()) will listen to all process events.
|
||||
///
|
||||
/// @param[in] url
|
||||
/// The url to connect to, e.g., 'connect://localhost:12345'.
|
||||
///
|
||||
/// @param[in] plugin_name
|
||||
/// The plugin name to be used; can be NULL.
|
||||
///
|
||||
/// @param[out]
|
||||
/// An error explaining what went wrong if the connect fails.
|
||||
///
|
||||
/// @return
|
||||
/// A process object for the connected process.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBProcess
|
||||
ConnectRemote (SBListener &listener,
|
||||
const char *url,
|
||||
const char *plugin_name,
|
||||
SBError& error);
|
||||
|
||||
lldb::SBFileSpec
|
||||
GetExecutable ();
|
||||
|
||||
bool
|
||||
AddModule (lldb::SBModule &module);
|
||||
|
||||
lldb::SBModule
|
||||
AddModule (const char *path,
|
||||
const char *triple,
|
||||
const char *uuid);
|
||||
|
||||
uint32_t
|
||||
GetNumModules () const;
|
||||
|
||||
lldb::SBModule
|
||||
GetModuleAtIndex (uint32_t idx);
|
||||
|
||||
bool
|
||||
RemoveModule (lldb::SBModule module);
|
||||
|
||||
lldb::SBDebugger
|
||||
GetDebugger() const;
|
||||
|
||||
lldb::SBModule
|
||||
FindModule (const lldb::SBFileSpec &file_spec);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set the base load address for a module section.
|
||||
///
|
||||
/// @param[in] section
|
||||
/// The section whose base load address will be set within this
|
||||
/// target.
|
||||
///
|
||||
/// @param[in] section_base_addr
|
||||
/// The base address for the section.
|
||||
///
|
||||
/// @return
|
||||
/// An error to indicate success, fail, and any reason for
|
||||
/// failure.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBError
|
||||
SetSectionLoadAddress (lldb::SBSection section,
|
||||
lldb::addr_t section_base_addr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Clear the base load address for a module section.
|
||||
///
|
||||
/// @param[in] section
|
||||
/// The section whose base load address will be cleared within
|
||||
/// this target.
|
||||
///
|
||||
/// @return
|
||||
/// An error to indicate success, fail, and any reason for
|
||||
/// failure.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBError
|
||||
ClearSectionLoadAddress (lldb::SBSection section);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Slide all file addresses for all module sections so that \a module
|
||||
/// appears to loaded at these slide addresses.
|
||||
///
|
||||
/// When you need all sections within a module to be loaded at a
|
||||
/// rigid slide from the addresses found in the module object file,
|
||||
/// this function will allow you to easily and quickly slide all
|
||||
/// module sections.
|
||||
///
|
||||
/// @param[in] module
|
||||
/// The module to load.
|
||||
///
|
||||
/// @param[in] sections_offset
|
||||
/// An offset that will be applied to all section file addresses
|
||||
/// (the virtual addresses found in the object file itself).
|
||||
///
|
||||
/// @return
|
||||
/// An error to indicate success, fail, and any reason for
|
||||
/// failure.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBError
|
||||
SetModuleLoadAddress (lldb::SBModule module,
|
||||
int64_t sections_offset);
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// The the section base load addresses for all sections in a module.
|
||||
///
|
||||
/// @param[in] module
|
||||
/// The module to unload.
|
||||
///
|
||||
/// @return
|
||||
/// An error to indicate success, fail, and any reason for
|
||||
/// failure.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBError
|
||||
ClearModuleLoadAddress (lldb::SBModule module);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Find functions by name.
|
||||
///
|
||||
/// @param[in] name
|
||||
/// The name of the function we are looking for.
|
||||
///
|
||||
/// @param[in] name_type_mask
|
||||
/// A logical OR of one or more FunctionNameType enum bits that
|
||||
/// indicate what kind of names should be used when doing the
|
||||
/// lookup. Bits include fully qualified names, base names,
|
||||
/// C++ methods, or ObjC selectors.
|
||||
/// See FunctionNameType for more details.
|
||||
///
|
||||
/// @param[in] append
|
||||
/// If true, any matches will be appended to \a sc_list, else
|
||||
/// matches replace the contents of \a sc_list.
|
||||
///
|
||||
/// @param[out] sc_list
|
||||
/// A symbol context list that gets filled in with all of the
|
||||
/// matches.
|
||||
///
|
||||
/// @return
|
||||
/// The number of matches added to \a sc_list.
|
||||
//------------------------------------------------------------------
|
||||
uint32_t
|
||||
FindFunctions (const char *name,
|
||||
uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
|
||||
bool append,
|
||||
lldb::SBSymbolContextList& sc_list);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Find global and static variables by name.
|
||||
///
|
||||
/// @param[in] name
|
||||
/// The name of the global or static variable we are looking
|
||||
/// for.
|
||||
///
|
||||
/// @param[in] max_matches
|
||||
/// Allow the number of matches to be limited to \a max_matches.
|
||||
///
|
||||
/// @return
|
||||
/// A list of matched variables in an SBValueList.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBValueList
|
||||
FindGlobalVariables (const char *name,
|
||||
uint32_t max_matches);
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
lldb::SBAddress
|
||||
ResolveLoadAddress (lldb::addr_t vm_addr);
|
||||
|
||||
SBSymbolContext
|
||||
ResolveSymbolContextForAddress (const SBAddress& addr,
|
||||
uint32_t resolve_scope);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateByLocation (const char *file, uint32_t line);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateByName (const char *symbol_name, const char *module_name = NULL);
|
||||
|
||||
// This version uses name_type_mask = eFunctionNameTypeAuto
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateByName (const char *symbol_name,
|
||||
const SBFileSpecList &module_list,
|
||||
const SBFileSpecList &comp_unit_list);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateByName (const char *symbol_name,
|
||||
uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
|
||||
const SBFileSpecList &module_list,
|
||||
const SBFileSpecList &comp_unit_list);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name = NULL);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateByRegex (const char *symbol_name_regex,
|
||||
const SBFileSpecList &module_list,
|
||||
const SBFileSpecList &comp_unit_list);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateBySourceRegex (const char *source_regex,
|
||||
const lldb::SBFileSpec &source_file,
|
||||
const char *module_name = NULL);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateBySourceRegex (const char *source_regex,
|
||||
const SBFileSpecList &module_list,
|
||||
const lldb::SBFileSpecList &source_file);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateByAddress (addr_t address);
|
||||
|
||||
uint32_t
|
||||
GetNumBreakpoints () const;
|
||||
|
||||
lldb::SBBreakpoint
|
||||
GetBreakpointAtIndex (uint32_t idx) const;
|
||||
|
||||
bool
|
||||
BreakpointDelete (break_id_t break_id);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
FindBreakpointByID (break_id_t break_id);
|
||||
|
||||
bool
|
||||
EnableAllBreakpoints ();
|
||||
|
||||
bool
|
||||
DisableAllBreakpoints ();
|
||||
|
||||
bool
|
||||
DeleteAllBreakpoints ();
|
||||
|
||||
uint32_t
|
||||
GetNumWatchpoints () const;
|
||||
|
||||
lldb::SBWatchpoint
|
||||
GetWatchpointAtIndex (uint32_t idx) const;
|
||||
|
||||
bool
|
||||
DeleteWatchpoint (lldb::watch_id_t watch_id);
|
||||
|
||||
lldb::SBWatchpoint
|
||||
FindWatchpointByID (lldb::watch_id_t watch_id);
|
||||
|
||||
lldb::SBWatchpoint
|
||||
WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write);
|
||||
|
||||
bool
|
||||
EnableAllWatchpoints ();
|
||||
|
||||
bool
|
||||
DisableAllWatchpoints ();
|
||||
|
||||
bool
|
||||
DeleteAllWatchpoints ();
|
||||
|
||||
lldb::SBBroadcaster
|
||||
GetBroadcaster () const;
|
||||
|
||||
lldb::SBType
|
||||
FindFirstType (const char* type);
|
||||
|
||||
lldb::SBTypeList
|
||||
FindTypes (const char* type);
|
||||
|
||||
SBSourceManager
|
||||
GetSourceManager();
|
||||
|
||||
#ifndef SWIG
|
||||
bool
|
||||
operator == (const lldb::SBTarget &rhs) const;
|
||||
|
||||
bool
|
||||
operator != (const lldb::SBTarget &rhs) const;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef SWIG
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level);
|
||||
#endif
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level) const;
|
||||
|
||||
protected:
|
||||
friend class SBAddress;
|
||||
friend class SBDebugger;
|
||||
friend class SBFunction;
|
||||
friend class SBInstruction;
|
||||
friend class SBModule;
|
||||
friend class SBProcess;
|
||||
friend class SBSourceManager;
|
||||
friend class SBSymbol;
|
||||
friend class SBValue;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Constructors are private, use static Target::Create function to
|
||||
// create an instance of this class.
|
||||
//------------------------------------------------------------------
|
||||
|
||||
SBTarget (const lldb::TargetSP& target_sp);
|
||||
|
||||
void
|
||||
reset (const lldb::TargetSP& target_sp);
|
||||
|
||||
lldb_private::Target *
|
||||
operator ->() const;
|
||||
|
||||
lldb_private::Target *
|
||||
get() const;
|
||||
|
||||
const lldb::TargetSP &
|
||||
get_sp () const;
|
||||
|
||||
private:
|
||||
//------------------------------------------------------------------
|
||||
// For Target only
|
||||
//------------------------------------------------------------------
|
||||
|
||||
lldb::TargetSP m_opaque_sp;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBTarget_h_
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user