Move everything under kotlin-native folder

I was forced to manually do update the following files, because otherwise
they would be ignored according .gitignore settings. Probably they
should be deleted from repo.

Interop/.idea/compiler.xml
Interop/.idea/gradle.xml
Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_runtime_1_0_3.xml
Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_0_3.xml
Interop/.idea/modules.xml
Interop/.idea/modules/Indexer/Indexer.iml
Interop/.idea/modules/Runtime/Runtime.iml
Interop/.idea/modules/StubGenerator/StubGenerator.iml
backend.native/backend.native.iml
backend.native/bc.frontend/bc.frontend.iml
backend.native/cli.bc/cli.bc.iml
backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt
backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt
backend.native/tests/link/lib/foo.kt
backend.native/tests/link/lib/foo2.kt
backend.native/tests/teamcity-test.property
This commit is contained in:
Stanislav Erokhin
2020-10-27 21:00:28 +03:00
parent 91e4162dad
commit f624800b84
2830 changed files with 0 additions and 0 deletions
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.konan.llvm
/**
* This code was generated with following command:
* $ clang -xc -E -Idist/dependencies/clang-llvm-3.9.0-darwin-macos/include/ llvmDebugInfoC/src/dwarf/include/dwarf_util.kt.pp -Wp,-P -Wp,-CC -o - | sed -e '/^$/d' -e '/^\ *\/\/.*$/d' > backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Dwarf.kt
*
*/
internal enum class DwarfTag(val value:Int) {
#define HANDLE_DW_TAG(ID, NAME) DW_TAG_##NAME(ID),
#include "llvm/Support/Dwarf.def"
#undef HANDLE_DW_TAG
}
internal enum class DwarfTypeKind(val value:Byte) {
#define HANDLE_DW_ATE(ID, NAME) DW_ATE_##NAME(ID),
#include "llvm/Support/Dwarf.def"
#undef HANDLE_DW_ATE
}
internal enum class DwarfOp(val value:Long) {
#define HANDLE_DW_OP(ID, NAME) DW_OP_##NAME(ID),
#include "llvm/Support/Dwarf.def"
#undef HANDLE_DW_OP
}
internal enum class DwarfLanguage(val value:Int) {
#define HANDLE_DW_LANG(ID, NAME) DW_LANG_##NAME(ID),
#include "llvm/Support/Dwarf.def"
#undef HANDLE_DW_LANG
DW_LANG_Kotlin(0x0001) /* manually added, should be changed someday. */
}
@@ -0,0 +1,297 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <assert.h>
#include <llvm/IR/DebugInfo.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/DIBuilder.h>
#include <llvm/IR/DebugInfoMetadata.h>
#include <llvm/IR/Instruction.h>
#include <llvm/Support/Casting.h>
#include <llvm-c/DebugInfo.h>
#include "DebugInfoC.h"
/**
* c++ --std=c++14 llvmDebugInfoC/src/DebugInfoC.cpp -IllvmDebugInfoC/include/ -Idependencies/all/clang+llvm-3.9.0-darwin-macos/include -Ldependencies/all/clang+llvm-3.9.0-darwin-macos/lib -lLLVMCore -lLLVMSupport -lncurses -shared -o libLLVMDebugInfoC.dylib
*/
namespace llvm {
//DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIBuilder, DIBuilderRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DICompileUnit, DICompileUnitRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIFile, DIFileRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIBasicType, DIBasicTypeRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DICompositeType, DICompositeTypeRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIType, DITypeOpaqueRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIDerivedType, DIDerivedTypeRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIModule, DIModuleRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIScope, DIScopeOpaqueRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DISubroutineType, DISubroutineTypeRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DISubprogram, DISubprogramRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DILocation, DILocationRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DILocalVariable, DILocalVariableRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIExpression, DIExpressionRef)
// from Module.cpp
//DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef)
}
/**
* see [DIFlags::FlagFwdDecl].
*/
#define DI_FORWARD_DECLARAION (4)
extern "C" {
void DIFinalize(DIBuilderRef builder) {
auto diBuilder = llvm::unwrap(builder);
diBuilder->finalize();
}
DICompileUnitRef DICreateCompilationUnit(DIBuilderRef builder, unsigned int lang,
const char *file, const char* dir,
const char * producer, int isOptimized,
const char * flags, unsigned int rv) {
llvm::DIBuilder *D = llvm::unwrap(builder);
return llvm::wrap(llvm::unwrap(builder)->createCompileUnit(lang, D->createFile(file, dir), producer, isOptimized, flags, rv));
}
DIFileRef DICreateFile(DIBuilderRef builder, const char *filename, const char *directory) {
return llvm::wrap(llvm::unwrap(builder)->createFile(filename, directory));
}
DIBasicTypeRef DICreateBasicType(DIBuilderRef builder, const char* name, uint64_t sizeInBits, uint64_t alignment, unsigned encoding) {
return llvm::wrap(llvm::unwrap(builder)->createBasicType(name, sizeInBits, encoding));
}
DIModuleRef DICreateModule(DIBuilderRef builder, DIScopeOpaqueRef scope,
const char* name, const char* configurationMacro,
const char* includePath, const char *iSysRoot) {
return llvm::wrap(llvm::unwrap(builder)->createModule(llvm::unwrap(scope), name, configurationMacro, includePath, iSysRoot));
}
DISubprogramRef DICreateFunction(DIBuilderRef builderRef, DIScopeOpaqueRef scope,
const char* name, const char *linkageName,
DIFileRef file, unsigned lineNo,
DISubroutineTypeRef type, int isLocal,
int isDefinition, unsigned scopeLine) {
auto builder = llvm::unwrap(builderRef);
auto subprogram = builder->createFunction(llvm::unwrap(scope),
name,
linkageName,
llvm::unwrap(file),
lineNo,
llvm::unwrap(type),
scopeLine, llvm::DINode::DIFlags::FlagZero, llvm::DISubprogram::toSPFlags(false, true, false));
auto tmp = subprogram->getRetainedNodes().get();
if (!tmp && tmp->isTemporary())
llvm::MDTuple::deleteTemporary(tmp);
builder->finalizeSubprogram(subprogram);
return llvm::wrap(subprogram);
}
DIScopeOpaqueRef DICreateLexicalBlockFile(DIBuilderRef builderRef, DIScopeOpaqueRef scopeRef, DIFileRef fileRef) {
return llvm::wrap(llvm::unwrap(builderRef)->createLexicalBlockFile(llvm::unwrap(scopeRef), llvm::unwrap(fileRef)));
}
DIScopeOpaqueRef DICreateLexicalBlock(DIBuilderRef builderRef, DIScopeOpaqueRef scopeRef, DIFileRef fileRef, int line, int column) {
return llvm::wrap(llvm::unwrap(builderRef)->createLexicalBlock(llvm::unwrap(scopeRef), llvm::unwrap(fileRef), line, column));
}
DICompositeTypeRef DICreateStructType(DIBuilderRef refBuilder,
DIScopeOpaqueRef scope, const char *name,
DIFileRef file, unsigned lineNumber,
uint64_t sizeInBits, uint64_t alignInBits,
unsigned flags, DITypeOpaqueRef derivedFrom,
DIDerivedTypeRef *elements,
uint64_t elementsCount,
DICompositeTypeRef refPlace) {
auto builder = llvm::unwrap(refBuilder);
if ((flags & DI_FORWARD_DECLARAION) != 0) {
auto tmp = builder->createReplaceableCompositeType(
llvm::dwarf::DW_TAG_structure_type, name, llvm::unwrap(scope), llvm::unwrap(file), lineNumber, 0, sizeInBits, alignInBits,
(llvm::DINode::DIFlags)flags);
builder->replaceTemporary(llvm::TempDIType(tmp), tmp);
builder->retainType(tmp);
return llvm::wrap(tmp);
}
assert(false);
return nullptr;
}
DICompositeTypeRef DICreateArrayType(DIBuilderRef refBuilder,
uint64_t size, uint64_t alignInBits,
DITypeOpaqueRef refType,
uint64_t elementsCount) {
auto builder = llvm::unwrap(refBuilder);
auto range = std::vector<llvm::Metadata*>({llvm::dyn_cast<llvm::Metadata>(builder->getOrCreateSubrange(0, size))});
auto type = builder->createArrayType(size, alignInBits, llvm::unwrap(refType),
builder->getOrCreateArray(range));
builder->retainType(type);
return llvm::wrap(type);
}
DIDerivedTypeRef DICreateMemberType(DIBuilderRef refBuilder,
DIScopeOpaqueRef refScope,
const char *name,
DIFileRef file,
unsigned lineNum,
uint64_t sizeInBits,
uint64_t alignInBits,
uint64_t offsetInBits,
unsigned flags,
DITypeOpaqueRef type) {
return llvm::wrap(llvm::unwrap(refBuilder)->createMemberType(
llvm::unwrap(refScope),
name,
llvm::unwrap(file),
lineNum,
sizeInBits,
alignInBits,
offsetInBits,
(llvm::DINode::DIFlags)flags,
llvm::unwrap(type)));
}
DICompositeTypeRef DICreateReplaceableCompositeType(DIBuilderRef refBuilder,
int tag,
const char *name,
DIScopeOpaqueRef refScope,
DIFileRef refFile,
unsigned line) {
auto builder = llvm::unwrap(refBuilder);
auto type = builder->createReplaceableCompositeType(
tag, name, llvm::unwrap(refScope), llvm::unwrap(refFile), line);
builder->retainType(type);
return llvm::wrap(type);
}
DIDerivedTypeRef DICreateReferenceType(DIBuilderRef refBuilder, DITypeOpaqueRef refType) {
auto builder = llvm::unwrap(refBuilder);
auto type = builder->createReferenceType(
llvm::dwarf::DW_TAG_reference_type,
llvm::unwrap(refType));
builder->retainType(type);
return llvm::wrap(type);
}
DIDerivedTypeRef DICreatePointerType(DIBuilderRef refBuilder, DITypeOpaqueRef refType) {
auto builder = llvm::unwrap(refBuilder);
auto type = builder->createReferenceType(
llvm::dwarf::DW_TAG_pointer_type,
llvm::unwrap(refType));
builder->retainType(type);
return llvm::wrap(type);
}
DISubroutineTypeRef DICreateSubroutineType(DIBuilderRef builder,
DITypeOpaqueRef* types,
unsigned typesCount) {
std::vector<llvm::Metadata *> parameterTypes;
for (int i = 0; i != typesCount; ++i) {
parameterTypes.push_back(llvm::unwrap(types[i]));
}
llvm::DIBuilder *b = llvm::unwrap(builder);
llvm::DITypeRefArray typeArray = b->getOrCreateTypeArray(parameterTypes);
auto type = b->createSubroutineType(typeArray);
b->retainType(type);
return llvm::wrap(type);
}
void DIFunctionAddSubprogram(LLVMValueRef fn, DISubprogramRef sp) {
auto f = llvm::cast<llvm::Function>(llvm::unwrap(fn));
auto dsp = llvm::cast<llvm::DISubprogram>(llvm::unwrap(sp));
f->setSubprogram(dsp);
if (!dsp->describes(f)) {
fprintf(stderr, "error!!! f:%s, sp:%s\n", f->getName().str().c_str(), dsp->getLinkageName().str().c_str());
}
}
DILocalVariableRef DICreateAutoVariable(DIBuilderRef builder, DIScopeOpaqueRef scope, const char *name, DIFileRef file, unsigned line, DITypeOpaqueRef type) {
return llvm::wrap(llvm::unwrap(builder)->createAutoVariable(
llvm::unwrap(scope),
name,
llvm::unwrap(file),
line,
llvm::unwrap(type)));
}
DILocalVariableRef DICreateParameterVariable(DIBuilderRef builder, DIScopeOpaqueRef scope, const char *name, unsigned argNo, DIFileRef file, unsigned line, DITypeOpaqueRef type) {
return llvm::wrap(llvm::unwrap(builder)->createParameterVariable(
llvm::unwrap(scope),
name,
argNo,
llvm::unwrap(file),
line,
llvm::unwrap(type)));
}
DIExpressionRef DICreateEmptyExpression(DIBuilderRef builder) {
return llvm::wrap(llvm::unwrap(builder)->createExpression());
}
void DIInsertDeclaration(DIBuilderRef builder, LLVMValueRef value, DILocalVariableRef localVariable, DILocationRef location, LLVMBasicBlockRef bb, int64_t *expr, uint64_t exprCount) {
auto di_builder = llvm::unwrap(builder);
std::vector<int64_t> expression;
for (uint64_t i = 0; i < exprCount; ++i)
expression.push_back(expr[i]);
di_builder->insertDeclare(llvm::unwrap(value),
llvm::unwrap(localVariable),
di_builder->createExpression(expression),
llvm::unwrap(location),
llvm::unwrap(bb));
}
DILocationRef LLVMCreateLocation(LLVMContextRef contextRef, unsigned line,
unsigned col, DIScopeOpaqueRef scope) {
auto location = llvm::DILocation::get(*llvm::unwrap(contextRef), line, col, llvm::unwrap(scope), nullptr);
return llvm::wrap(location);
}
DILocationRef LLVMCreateLocationInlinedAt(LLVMContextRef contextRef, unsigned line,
unsigned col, DIScopeOpaqueRef scope, DILocationRef refLocationInlinedAt) {
auto location = llvm::DILocation::get(*llvm::unwrap(contextRef), line, col, llvm::unwrap(scope), llvm::unwrap(refLocationInlinedAt));
return llvm::wrap(location);
}
void LLVMBuilderSetDebugLocation(LLVMBuilderRef builder, DILocationRef refLocation) {
llvm::unwrap(builder)->SetCurrentDebugLocation(llvm::unwrap(refLocation));
}
void LLVMBuilderResetDebugLocation(LLVMBuilderRef builder) {
llvm::unwrap(builder)->SetCurrentDebugLocation(nullptr);
}
LLVMValueRef LLVMBuilderGetCurrentFunction(LLVMBuilderRef builder) {
return llvm::wrap(llvm::unwrap(builder)->GetInsertBlock()->getParent());
}
const char* LLVMBuilderGetCurrentBbName(LLVMBuilderRef builder) {
return llvm::unwrap(builder)->GetInsertBlock()->getName().str().c_str();
}
const char *DIGetSubprogramLinkName(DISubprogramRef sp) {
return llvm::unwrap(sp)->getLinkageName().str().c_str();
}
int DISubprogramDescribesFunction(DISubprogramRef sp, LLVMValueRef fn) {
return llvm::unwrap(sp)->describes(llvm::cast<llvm::Function>(llvm::unwrap(fn)));
}
} /* extern "C" */
@@ -0,0 +1,116 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __DEBUG_INFO_C_H__
# define __DEBUG_INFO_C_H__
#include <llvm-c/Core.h>
# ifdef __cplusplus
extern "C" {
# endif
typedef struct LLVMOpaqueDIBuilder *DIBuilderRef;
//typedef struct DIBuilder *DIBuilderRef;
typedef struct DICompileUnit *DICompileUnitRef;
typedef struct DIFile *DIFileRef;
typedef struct DIBasicType *DIBasicTypeRef;
typedef struct DICompositeType *DICompositeTypeRef;
typedef struct DIDerivedType *DIDerivedTypeRef;
typedef struct DIType *DITypeOpaqueRef;
typedef struct DISubprogram *DISubprogramRef;
typedef struct DIModule *DIModuleRef;
typedef struct DIScope *DIScopeOpaqueRef;
typedef struct DISubroutineType *DISubroutineTypeRef;
//typedef struct DISubprogram *DISubprogramRef;
typedef struct DILocation *DILocationRef;
typedef struct DILocalVariable *DILocalVariableRef;
typedef struct DIExpression *DIExpressionRef;
void DIFinalize(DIBuilderRef builder);
DICompileUnitRef DICreateCompilationUnit(DIBuilderRef builder, unsigned int lang, const char *File, const char* dir, const char * producer, int isOptimized, const char * flags, unsigned int rv);
DIFileRef DICreateFile(DIBuilderRef builder, const char *filename, const char *directory);
DIBasicTypeRef DICreateBasicType(DIBuilderRef builder, const char* name, uint64_t sizeInBits, uint64_t alignment, unsigned encoding);
DICompositeTypeRef DICreateStructType(DIBuilderRef refBuilder,
DIScopeOpaqueRef scope, const char *name,
DIFileRef file, unsigned lineNumber,
uint64_t sizeInBits, uint64_t alignInBits,
unsigned flags, DITypeOpaqueRef derivedFrom,
DIDerivedTypeRef *elements,
uint64_t elementsCount,
DICompositeTypeRef refPlace);
DICompositeTypeRef DICreateArrayType(DIBuilderRef refBuilder,
uint64_t size, uint64_t alignInBits,
DITypeOpaqueRef type,
uint64_t elementsCount);
DIDerivedTypeRef DICreateReferenceType(DIBuilderRef refBuilder, DITypeOpaqueRef refType);
DIDerivedTypeRef DICreatePointerType(DIBuilderRef refBuilder, DITypeOpaqueRef refType);
DICompositeTypeRef DICreateReplaceableCompositeType(DIBuilderRef refBuilder,
int tag,
const char *name,
DIScopeOpaqueRef refScope,
DIFileRef refFile,
unsigned line);
DIDerivedTypeRef DICreateMemberType(DIBuilderRef refBuilder,
DIScopeOpaqueRef refScope,
const char *name,
DIFileRef file,
unsigned lineNum,
uint64_t sizeInBits,
uint64_t alignInBits,
uint64_t offsetInBits,
unsigned flags,
DITypeOpaqueRef type);
DIModuleRef DICreateModule(DIBuilderRef builder, DIScopeOpaqueRef scope,
const char* name, const char* configurationMacro,
const char* includePath, const char *iSysRoot);
DIScopeOpaqueRef DICreateLexicalBlockFile(DIBuilderRef builderRef, DIScopeOpaqueRef scopeRef, DIFileRef fileRef);
DIScopeOpaqueRef DICreateLexicalBlock(DIBuilderRef builderRef, DIScopeOpaqueRef scopeRef, DIFileRef fileRef, int line, int column);
DISubprogramRef DICreateFunction(DIBuilderRef builder, DIScopeOpaqueRef scope,
const char* name, const char *linkageName,
DIFileRef file, unsigned lineNo,
DISubroutineTypeRef type, int isLocal,
int isDefinition, unsigned scopeLine);
DISubroutineTypeRef DICreateSubroutineType(DIBuilderRef builder,
DITypeOpaqueRef* types,
unsigned typesCount);
DILocalVariableRef DICreateAutoVariable(DIBuilderRef builder, DIScopeOpaqueRef scope, const char *name, DIFileRef file, unsigned line, DITypeOpaqueRef type);
DILocalVariableRef DICreateParameterVariable(DIBuilderRef builder, DIScopeOpaqueRef scope, const char *name, unsigned argNo, DIFileRef file, unsigned line, DITypeOpaqueRef type);
void DIInsertDeclaration(DIBuilderRef builder, LLVMValueRef value, DILocalVariableRef localVariable, DILocationRef location, LLVMBasicBlockRef bb, int64_t *expr, uint64_t exprCount);
DIExpressionRef DICreateEmptyExpression(DIBuilderRef builder);
void DIFunctionAddSubprogram(LLVMValueRef fn, DISubprogramRef sp);
DILocationRef LLVMCreateLocation(LLVMContextRef contextRef, unsigned line, unsigned col, DIScopeOpaqueRef scope);
DILocationRef LLVMCreateLocationInlinedAt(LLVMContextRef contextRef, unsigned line, unsigned col, DIScopeOpaqueRef scope, DILocationRef refLocation);
void LLVMBuilderSetDebugLocation(LLVMBuilderRef builder, DILocationRef refLocation);
void LLVMBuilderResetDebugLocation(LLVMBuilderRef builder);
const char* LLVMBuilderGetCurrentBbName(LLVMBuilderRef builder);
const char *DIGetSubprogramLinkName(DISubprogramRef sp);
LLVMValueRef LLVMBuilderGetCurrentFunction(LLVMBuilderRef builder);
int DISubprogramDescribesFunction(DISubprogramRef sp, LLVMValueRef fn);
# ifdef __cplusplus
}
# endif
#endif
@@ -0,0 +1,490 @@
#!/usr/bin/python
##
# Copyright 2010-2017 JetBrains s.r.o.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# (lldb) command script import llvmDebugInfoC/src/scripts/konan_lldb.py
# (lldb) p kotlin_variable
#
import lldb
import struct
import re
import sys
NULL = 'null'
def log(msg):
if False:
print(msg(), file=sys.stderr)
def exelog(stmt):
if False:
f = open(os.getenv('HOME', '') + "/lldbexelog.txt", "a")
f.write(stmt())
f.write("\n")
f.close()
def lldb_val_to_ptr(lldb_val):
addr = lldb_val.GetValueAsUnsigned()
return '((struct ObjHeader *) {:#x})'.format(addr)
def evaluate(expr):
result = lldb.debugger.GetSelectedTarget().EvaluateExpression(expr, lldb.SBExpressionOptions())
evallog = lambda : "{} => {}".format(expr, result)
log(evallog)
exelog(evallog)
return result
def _symbol_loaded_address(name, debugger = lldb.debugger):
target = debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetSelectedThread()
frame = thread.GetSelectedFrame()
candidates = list(filter(lambda x: x.name == name, frame.module.symbols))
# take first
for candidate in candidates:
address = candidate.GetStartAddress().GetLoadAddress(target)
log(lambda: "_symbol_loaded_address:{} {:#x}".format(name, address))
return address
def _type_info_by_address(address, debugger = lldb.debugger):
target = debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetSelectedThread()
frame = thread.GetSelectedFrame()
candidates = list(filter(lambda x: x.GetStartAddress().GetLoadAddress(target) == address, frame.module.symbols))
return candidates
def is_instance_of(addr, typeinfo):
return evaluate("(bool)IsInstance({}, {:#x})".format(addr, typeinfo)).GetValue() == "true"
def is_string_or_array(value):
return evaluate("(int)IsInstance({0}, {1}) ? 1 : ((int)Konan_DebugIsArray({0}) ? 2 : 0)".format(lldb_val_to_ptr(value), _symbol_loaded_address('kclass:kotlin.String'))).unsigned
def type_info(value):
"""This method checks self-referencing of pointer of first member of TypeInfo including case when object has an
meta-object pointed by TypeInfo. Two lower bits are reserved for memory management needs see runtime/src/main/cpp/Memory.h."""
if value.GetTypeName() != "ObjHeader *":
return False
expr = "*(void **)((uintptr_t)(*(void**){0:#x}) & ~0x3) == **(void***)((uintptr_t)(*(void**){0:#x}) & ~0x3) ? *(void **)((uintptr_t)(*(void**){0:#x}) & ~0x3) : (void *)0".format(value.unsigned)
result = evaluate(expr)
return result.unsigned if result.IsValid() and result.unsigned != 0 else None
__FACTORY = {}
# Cache type info pointer to [ChildMetaInfo]
SYNTHETIC_OBJECT_LAYOUT_CACHE = {}
TO_STRING_DEPTH = 2
ARRAY_TO_STRING_LIMIT = 10
def kotlin_object_type_summary(lldb_val, internal_dict = {}):
"""Hook that is run by lldb to display a Kotlin object."""
log(lambda: "kotlin_object_type_summary({:#x}, {})".format(lldb_val.unsigned, internal_dict))
fallback = lldb_val.GetValue()
if str(lldb_val.type) != "struct ObjHeader *":
if lldb_val.GetValue() is None:
return NULL
return lldb_val.GetValueAsSigned()
if lldb_val.unsigned == 0:
return NULL
tip = internal_dict["type_info"] if "type_info" in internal_dict.keys() else type_info(lldb_val)
if not tip:
return fallback
return select_provider(lldb_val, tip, internal_dict).to_string()
def select_provider(lldb_val, tip, internal_dict):
log(lambda : "select_provider: name:{} : {}, {}".format(lldb_val.name, lldb_val, internal_dict))
soa = is_string_or_array(lldb_val)
log(lambda : "select_provider: {} : soa: {}".format(lldb_val, soa))
return __FACTORY['string'](lldb_val, tip, internal_dict) if soa == 1 else __FACTORY['array'](lldb_val, tip, internal_dict) if soa == 2 \
else __FACTORY['object'](lldb_val, tip, internal_dict)
class KonanHelperProvider(lldb.SBSyntheticValueProvider):
def __init__(self, valobj, amString, internal_dict = {}):
self._target = lldb.debugger.GetSelectedTarget()
self._process = self._target.GetProcess()
self._valobj = valobj
self._ptr = lldb_val_to_ptr(self._valobj)
if amString:
return
self._internal_dict = internal_dict.copy()
self._to_string_depth = TO_STRING_DEPTH if "to_string_depth" not in self._internal_dict.keys() else self._internal_dict["to_string_depth"]
if self._children_count == 0:
self._children_count = evaluate("(int)Konan_DebugGetFieldCount({})".format(self._ptr)).signed
self._children = []
self._type_conversion = [
lambda address, name: self._valobj.CreateValueFromExpression(name, "(void *){:#x}".format(address)),
lambda address, name: self._create_synthetic_child(address, name),
lambda address, name: self._valobj.CreateValueFromExpression(name, "(int8_t *){:#x}".format(address)),
lambda address, name: self._valobj.CreateValueFromExpression(name, "(int16_t *){:#x}".format(address)),
lambda address, name: self._valobj.CreateValueFromExpression(name, "(int32_t *){:#x}".format(address)),
lambda address, name: self._valobj.CreateValueFromExpression(name, "(int64_t *){:#x}".format(address)),
lambda address, name: self._valobj.CreateValueFromExpression(name, "(float *){:#x}".format(address)),
lambda address, name: self._valobj.CreateValueFromExpression(name, "(double *){:#x}".format(address)),
lambda address, name: self._valobj.CreateValueFromExpression(name, "(void **){:#x}".format(address)),
lambda address, name: self._valobj.CreateValueFromExpression(name, "(bool *){:#x}".format(address)),
lambda address, name: None]
self._types = [
valobj.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType(),
valobj.GetType(),
valobj.GetType().GetBasicType(lldb.eBasicTypeChar),
valobj.GetType().GetBasicType(lldb.eBasicTypeShort),
valobj.GetType().GetBasicType(lldb.eBasicTypeInt),
valobj.GetType().GetBasicType(lldb.eBasicTypeLongLong),
valobj.GetType().GetBasicType(lldb.eBasicTypeFloat),
valobj.GetType().GetBasicType(lldb.eBasicTypeDouble),
valobj.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType(),
valobj.GetType().GetBasicType(lldb.eBasicTypeBool)
]
def _read_string(self, expr, error):
return self._process.ReadCStringFromMemory(evaluate(expr).unsigned, 0x1000, error)
def _read_value(self, index):
value_type = self._children[index].type()
address = self._valobj.unsigned + self._children[index].offset()
return self._type_conversion[int(value_type)](address, str(self._children[index].name()))
def _create_synthetic_child(self, address, name):
if self._to_string_depth == 0:
return None
index = self.get_child_index(name)
value = self._valobj.CreateChildAtOffset(str(name),
self._children[index].offset(),
self._read_type(index))
value.SetSyntheticChildrenGenerated(True)
value.SetPreferSyntheticValue(True)
return value
def _read_type(self, index):
type = self._types[self._children[index].type()]
log(lambda: "type:{0} of {1:#x} of {2:#x}".format(type, self._valobj.unsigned, self._valobj.unsigned + self._children[index].offset()))
return type
def _deref_or_obj_summary(self, index, internal_dict):
value = self._values[index]
if not value:
log(lambda : "_deref_or_obj_summary: value none, index:{}, type:{}".format(index, self._children[index].type()))
return None
tip = type_info(value)
if tip:
internal_dict["type_info"] = tip
return kotlin_object_type_summary(value, internal_dict)
tip = type_info(value.deref)
if tip:
internal_dict["type_info"] = tip
return kotlin_object_type_summary(value.deref, internal_dict)
return kotlin_object_type_summary(value.deref, internal_dict)
def _field_address(self, index):
return evaluate("(void *)Konan_DebugGetFieldAddress({}, {})".format(self._ptr, index)).unsigned
def _field_type(self, index):
return evaluate("(int)Konan_DebugGetFieldType({}, {})".format(self._ptr, index)).unsigned
class KonanStringSyntheticProvider(KonanHelperProvider):
def __init__(self, valobj):
self._children_count = 0
super(KonanStringSyntheticProvider, self).__init__(valobj, True)
fallback = valobj.GetValue()
buff_addr = evaluate("(void *)Konan_DebugBuffer()").unsigned
buff_len = evaluate(
'(int)Konan_DebugObjectToUtf8Array({}, (void *){:#x}, (int)Konan_DebugBufferSize());'.format(
self._ptr, buff_addr)
).signed
if not buff_len:
self._representation = fallback
return
error = lldb.SBError()
s = self._process.ReadCStringFromMemory(int(buff_addr), int(buff_len), error)
if not error.Success():
raise DebuggerException()
self._representation = s if error.Success() else fallback
self._logger = lldb.formatters.Logger.Logger()
def update(self):
pass
def num_children(self):
return 0
def has_children(self):
return False
def get_child_index(self, _):
return None
def get_child_at_index(self, _):
return None
def to_string(self):
return self._representation
class DebuggerException(Exception):
pass
class MemberLayout:
def __init__(self, name, type, offset):
self._name = name
self._type = type
self._offset = offset
def name(self):
return self._name
def type(self):
return self._type
def offset(self):
return self._offset
class KonanObjectSyntheticProvider(KonanHelperProvider):
def __init__(self, valobj, tip, internal_dict):
# Save an extra call into the process
if tip in SYNTHETIC_OBJECT_LAYOUT_CACHE:
log(lambda : "TIP: {:#x} EARLYHIT".format(tip))
self._children = SYNTHETIC_OBJECT_LAYOUT_CACHE[tip]
self._children_count = len(self._children)
else:
self._children_count = 0
super(KonanObjectSyntheticProvider, self).__init__(valobj, False, internal_dict)
if not tip in SYNTHETIC_OBJECT_LAYOUT_CACHE:
SYNTHETIC_OBJECT_LAYOUT_CACHE[tip] = [
MemberLayout(self._field_name(i), self._field_type(i), self._field_address(i) - self._valobj.unsigned)
for i in range(self._children_count)]
log(lambda : "TIP: {:#x} MISSED".format(tip))
else:
log(lambda : "TIP: {:#x} HIT".format(tip))
self._children = SYNTHETIC_OBJECT_LAYOUT_CACHE[tip]
self._values = [self._read_value(index) for index in range(self._children_count)]
def _field_name(self, index):
error = lldb.SBError()
name = self._read_string("(void *)Konan_DebugGetFieldName({}, (int){})".format(self._ptr, index), error)
if not error.Success():
raise DebuggerException()
return name
def num_children(self):
return self._children_count
def has_children(self):
return self._children_count > 0
def get_child_index(self, name):
def __none(iterable, f):
return not any(f(x) for x in iterable)
if __none(self._children, lambda x: x.name() == name):
return -1
return next(i for i,v in enumerate(self._children) if v.name() == name)
def get_child_at_index(self, index):
result = self._values[index]
if result is None:
result = self._read_value(index)
self._values[index] = result
return result
# TODO: fix cyclic structures stringification.
def to_string(self):
if self._to_string_depth == 0:
return "..."
else:
internal_dict = self._internal_dict.copy()
internal_dict["to_string_depth"] = self._to_string_depth - 1
return dict([(self._children[i].name(), self._deref_or_obj_summary(i, internal_dict)) for i in range(self._children_count)])
class KonanArraySyntheticProvider(KonanHelperProvider):
def __init__(self, valobj, internal_dict):
self._children_count = 0
super(KonanArraySyntheticProvider, self).__init__(valobj, False, internal_dict)
if self._ptr is None:
return
valobj.SetSyntheticChildrenGenerated(True)
type = self._field_type(0)
zerro_address = self._field_address(0)
first_address = self._field_address(1)
offset = zerro_address - valobj.unsigned
size = first_address - zerro_address
self._children = [MemberLayout(str(x), type, offset + x * size) for x in range(self.num_children())]
self._values = [self._read_value(i) for i in range(min(ARRAY_TO_STRING_LIMIT, self._children_count))]
def cap_children_count(self):
return self._children_count
def num_children(self):
return self.cap_children_count()
def has_children(self):
return self._children_count > 0
def get_child_index(self, name):
index = int(name)
return index if (0 <= index < self._children_count) else -1
def get_child_at_index(self, index):
result = self._values[index]
if result is None:
result = self._read_value(index)
self._values[index] = result
return result
def to_string(self):
return [self._deref_or_obj_summary(i, self._internal_dict.copy()) for i in range(min(ARRAY_TO_STRING_LIMIT, self._children_count))]
class KonanProxyTypeProvider:
def __init__(self, valobj, internal_dict):
log(lambda : "KonanProxyTypeProvider: {:#x}".format(valobj.unsigned))
tip = type_info(valobj)
if not tip:
return
log(lambda : "KonanProxyTypeProvider: tip: {:#x}".format(tip))
self._proxy = select_provider(valobj, tip, internal_dict)
log(lambda: "KonanProxyTypeProvider: _proxy: {}".format(self._proxy.__class__.__name__))
self.update()
def __getattr__(self, item):
return getattr(self._proxy, item)
def clear_cache_command(debugger, command, result, internal_dict):
SYNTHETIC_OBJECT_LAYOUT_CACHE.clear()
def type_name_command(debugger, command, result, internal_dict):
result.AppendMessage(evaluate('(char *)Konan_DebugGetTypeName({})'.format(command)).summary)
__KONAN_VARIABLE = re.compile('kvar:(.*)#internal')
__KONAN_VARIABLE_TYPE = re.compile('^kfun:<get-(.*)>\\(\\)(.*)$')
__TYPES_KONAN_TO_C = {
'kotlin.Byte': ('int8_t', lambda v: v.signed),
'kotlin.Short': ('short', lambda v: v.signed),
'kotlin.Int': ('int', lambda v: v.signed),
'kotlin.Long': ('long', lambda v: v.signed),
'kotlin.UByte': ('int8_t', lambda v: v.unsigned),
'kotlin.UShort': ('short', lambda v: v.unsigned),
'kotlin.UInt': ('int', lambda v: v.unsigned),
'kotlin.ULong': ('long', lambda v: v.unsigned),
'kotlin.Char': ('short', lambda v: v.signed),
'kotlin.Boolean': ('bool', lambda v: v.signed),
'kotlin.Float': ('float', lambda v: v.value),
'kotlin.Double': ('double', lambda v: v.value)
}
def type_by_address_command(debugger, command, result, internal_dict):
result.AppendMessage("DEBUG: {}".format(command))
tokens = command.split()
target = debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetSelectedThread()
types = _type_info_by_address(tokens[0])
result.AppendMessage("DEBUG: {}".format(types))
for t in types:
result.AppendMessage("{}: {:#x}".format(t.name, t.GetStartAddress().GetLoadAddress(target)))
def symbol_by_name_command(debugger, command, result, internal_dict):
target = debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetSelectedThread()
frame = thread.GetSelectedFrame()
tokens = command.split()
mask = re.compile(tokens[0])
symbols = list(filter(lambda v: mask.match(v.name), frame.GetModule().symbols))
visited = list()
for symbol in symbols:
name = symbol.name
if name in visited:
continue
visited.append(name)
result.AppendMessage("{}: {:#x}".format(name, symbol.GetStartAddress().GetLoadAddress(target)))
def konan_globals_command(debugger, command, result, internal_dict):
target = debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetSelectedThread()
frame = thread.GetSelectedFrame()
konan_variable_symbols = list(filter(lambda v: __KONAN_VARIABLE.match(v.name), frame.GetModule().symbols))
visited = list()
for symbol in konan_variable_symbols:
name = __KONAN_VARIABLE.search(symbol.name).group(1)
if name in visited:
continue
visited.append(name)
getters = list(filter(lambda v: re.match('^kfun:<get-{}>\\(\\).*$'.format(name), v.name), frame.module.symbols))
if not getters:
result.AppendMessage("storage not found for name:{}".format(name))
continue
getter_functions = frame.module.FindFunctions(getters[0].name)
if not getter_functions:
continue
address = getter_functions[0].function.GetStartAddress().GetLoadAddress(target)
type = __KONAN_VARIABLE_TYPE.search(getters[0].name).group(2)
(c_type, extractor) = __TYPES_KONAN_TO_C[type] if type in __TYPES_KONAN_TO_C.keys() else ('struct ObjHeader *', lambda v: kotlin_object_type_summary(v))
value = evaluate('(({0} (*)()){1:#x})()'.format(c_type, address))
str_value = extractor(value)
result.AppendMessage('{} {}: {}'.format(type, name, str_value))
def __lldb_init_module(debugger, _):
__FACTORY['object'] = lambda x, y, z: KonanObjectSyntheticProvider(x, y, z)
__FACTORY['array'] = lambda x, y, z: KonanArraySyntheticProvider(x, z)
__FACTORY['string'] = lambda x, y, _: KonanStringSyntheticProvider(x)
debugger.HandleCommand('\
type summary add \
--no-value \
--expand \
--python-function konan_lldb.kotlin_object_type_summary \
"struct ObjHeader *" \
--category Kotlin\
')
debugger.HandleCommand('\
type synthetic add \
--python-class konan_lldb.KonanProxyTypeProvider\
"ObjHeader *" \
--category Kotlin\
')
debugger.HandleCommand('type category enable Kotlin')
debugger.HandleCommand('command script add -f {}.clear_cache_command clear_kotlin_cache'.format(__name__))
debugger.HandleCommand('command script add -f {}.type_name_command type_name'.format(__name__))
debugger.HandleCommand('command script add -f {}.type_by_address_command type_by_address'.format(__name__))
debugger.HandleCommand('command script add -f {}.symbol_by_name_command symbol_by_name'.format(__name__))