LLVM IR: выставить переменные в GDB? - PullRequest
0 голосов
/ 28 ноября 2018

Я пишу пользовательский язык программирования.Я генерирую LLVM IR в качестве промежуточного (через LLVMlite), и я хочу представить переменные для GDB.Это пример сгенерированного IR:

; ModuleID = "tests/debuginfo.xan"
source_filename = "debuginfo.xan"
target triple = "x86_64-unknown-linux-gnu"
target datalayout = ""

define void @"main"(i32 %".1", i8** %".2") !dbg !10
{
entry:
  %"$argc" = alloca i32
  store i32 %".1", i32* %"$argc"
  %"$argv" = alloca i8**
  store i8** %".2", i8*** %"$argv"
  %"$a" = alloca i32
  call void @"llvm.dbg.declare"(metadata i32* %"$a", metadata !12, metadata !13), !dbg !14
  call void @"llvm.dbg.value"(metadata i32 0, metadata !12, metadata !13), !dbg !15
  store i32 0, i32* %"$a"
  ret void
}

declare i32 @"printf"(i8* %".1", ...) 

declare void @"llvm.dbg.declare"(metadata %".1", metadata %".2", metadata %".3") nounwind readnone

declare void @"llvm.dbg.value"(metadata %".1", metadata %".2", metadata %".3") nounwind readnone

@"NULL" = internal constant i8* inttoptr (i32 0 to i8*)
!llvm.dbg.cu = !{ !2 }
!llvm.module.flags = !{ !3, !4, !5 }
!llvm.ident = !{ !6 }
!gen-by = !{ !16 }
!0 = !DIFile(directory: "/home/proc-daemon/Dropbox/Xanathar/xanathar/tests", filename: "debuginfo.xan")
!1 = !{  }
!2 = distinct !DICompileUnit(emissionKind: FullDebug, enums: !1, file: !0, isOptimized: false, language: DW_LANG_Python, producer: "Xanathar v. a0.0.1", runtimeVersion: 0)
!3 = !{ i32 2, !"Dwarf Version", i32 4 }
!4 = !{ i32 2, !"Debug Info Version", i32 3 }
!5 = !{ i32 1, !"wchar_size", i32 4 }
!6 = !{ !"Xanathar a0.0.1" }
!7 = !DIDerivedType(baseType: null, size: 64, tag: DW_TAG_pointer_type)
!8 = !{ !7 }
!9 = !DISubroutineType(types: !8)
!10 = distinct !DISubprogram(file: !0, isDefinition: true, isLocal: false, isOptimized: false, name: "main", scope: !0, scopeLine: 1, type: !9, unit: !2, variables: !1)
!11 = !DIBasicType(encoding: DW_ATE_signed, name: "int", size: 4)
!12 = !DILocalVariable(file: !0, line: 1, name: "a", scope: !10, type: !11)
!13 = !DIExpression()
!14 = !DILocation(column: 1, line: 1, scope: !10)
!15 = !DILocation(column: 1, line: 2, scope: !10)
!16 = !{ !"Xanathar" }

Я удалил предыдущие изменения.Код генерации можно найти здесь .Как видите, у меня есть переменная $a, которую я пытаюсь объявить с помощью llvm.dbg.declare.Однако, хотя objdump --sym отображает информацию об отладке ( pastebin ), GDB выдает No locals. при запуске info locals.Как правильно экспортировать переменные?Как я могу сгенерировать это с помощью LLVMlite?


Вот код компиляции:

 def compile(self, name, so):
        sys.stderr.write('---COMPILE---\n')
        if not so:
            command = 'clang {0} -g -fstandalone-debug -O0 ' + name + '.ll '
        else:
            command = 'clang {0} -g -fstandalone-debug -O0 -shared -undefined dynamic_lookup ' + name + '.ll '

        command = command.format(self.flags)

        for i in self.LOADED_MODULES:
            if i["type"] == 'LINKED_SO':
                command += os.path.abspath(i["FILE"]) + ' '
        command = command + '-o ' + name + ('.so' if so else '.o')
        # print(command)
        os.system(command)

Вот код подтверждения LLVM:

def _compile_ir(self, builder):
    """
    Compile the LLVM IR string with the given engine.
    The compiled module object is returned.
    """
    # Create a LLVM module object from the IR
    self.builder = builder
    self.builder.ret_void()
    self.module.add_named_metadata("gen-by", ["Xanathar"])
    llvm_ir = str(self.module)
    try:
        mod = self.binding.parse_assembly(llvm_ir)
    except RuntimeError as e:
        sys.stderr.write("[ERR] LLVM parsing error!\n")
        sys.stderr.write(str(e))
        if "expected instruction opcode" in str(e):
            sys.stderr.write("\nDid you forget to return from a function?")
        exit(1)

        mod = 0  # Otherwise PyCharm complains about mod's usage below

    mod.verify()
    # Now add the module and make sure it is ready for execution
    self.engine.add_module(mod)
    self.engine.finalize_object()
    self.engine.run_static_constructors()
    return mod

(Послеэто, модуль записывается в файл)

EDIT 5 (или 6, idk): Как предложил Чираг Патель, я добавил новый оператор отладки в инструкцию ret.Затем это произошло.

(gdb) r
Starting program: /home/proc-daemon/Dropbox/Xanathar/xanathar/tests/debuginfo.xan.o 

Breakpoint 1, main () at debuginfo.xan:1
1       declare $a as int32;
(gdb) info locals
Segmentation fault (core dumped)
...