Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GDB JIT Interface simpliest example

I read the JIT Interface chapter and faced the problem: how to write a simpliest example for simpliest possible code (preferably in C++ and at least for x86-64 platform)? Say, I want to debug the following code (namely, code_.data() function):

#include "eallocator.hpp"

#include <iostream>
#include <vector>

#include <cstdlib>

int main()
{
    std::vector< std::uint8_t, eallocator< std::uint8_t > > code_;
    code_.push_back(0b11011001u); code_.push_back(0b11101011u); // fldpi
    code_.push_back(0b11000011u);                               // ret

    double result_;
    __asm("call *%1"
            : "=&t"(result_)
            : "r"(code_.data())
            :
              );
    std::cout << result_ << std::endl;

    return EXIT_SUCCESS;
}

What (minimally) I should to do to use the interface? Particularly, I want to be able to provide some pseudocode (arbitrary text in memory) as "source" (with corresponding lines info) if it possible.

How to instrument the above code (or something similar), while remaining terse.

#include "eallocator.hpp" should use the approaches from this for Windows or from this for Linux.

like image 688
Tomilov Anatoliy Avatar asked Nov 18 '13 11:11

Tomilov Anatoliy


2 Answers

If I understand you correctly, what you're trying to do is to dynamically emit some executable code into memory and set up GDB to be able to debug it, is that correct?

What makes this task quite difficult to express in a "minimal" example is that GDB actually expects to find a whole ELF object in memory, not just a lump of code. GDB's registration interfaces need ELF symbol tables to examine in order to figure out which symbols exist in the emitted code and where they reside.

Your best bet to do this without unreasonable effort is to look at LLVM. The Debugging JIT-ed Code with GDB section in the documentation describes how to do this with MCJIT, with a full example at the bottom - going from some simple C code, JITing it to memory with LLVM MCJIT and attaching GDB to it. Moreover, since the LLVM MCJIT framework is involved you get full debug info there, up to the C level!

To be honest, that documentation section has not been updated in a while, but it should work. Let me know if it doesn't - I'll look into fixing things and updating it.

I hope this helps.

like image 126
Eli Bendersky Avatar answered Nov 09 '22 17:11

Eli Bendersky


There is an example in their tests which should help

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/testsuite/gdb.base/jit-main.c

like image 44
ReDucTor Avatar answered Nov 09 '22 18:11

ReDucTor