Previous: Using JIT Debug Info Readers, Up: Custom Debug Info

#### 29.4.2 Writing JIT Debug Info Readers

As mentioned, a reader is essentially a shared object conforming to a certain ABI. This ABI is described in `jit-reader.h`.

`jit-reader.h` defines the structures, macros and functions required to write a reader. It is installed (along with gdb), in `includedir/gdb` where includedir is the system include directory.

Readers need to be released under a GPL compatible license. A reader can be declared as released under such a license by placing the macro `GDB_DECLARE_GPL_COMPATIBLE_READER` in a source file.

The entry point for readers is the symbol `gdb_init_reader`, which is expected to be a function with the prototype

         extern struct gdb_reader_funcs *gdb_init_reader (void);

`struct gdb_reader_funcs` contains a set of pointers to callback functions. These functions are executed to read the debug info generated by the JIT compiler (`read`), to unwind stack frames (`unwind`) and to create canonical frame IDs (`get_Frame_id`). It also has a callback that is called when the reader is being unloaded (`destroy`). The struct looks like this

         struct gdb_reader_funcs
         {
           /* Must be set to GDB_READER_INTERFACE_VERSION.  */
           int reader_version;

           /* For use by the reader.  */
           void *priv_data;

           gdb_read_debug_info *read;
           gdb_unwind_frame *unwind;
           gdb_get_frame_id *get_frame_id;
           gdb_destroy_reader *destroy;
         };

The callbacks are provided with another set of callbacks by gdb to do their job. For `read`, these callbacks are passed in a `struct gdb_symbol_callbacks` and for `unwind` and `get_frame_id`, in a `struct gdb_unwind_callbacks`. `struct gdb_symbol_callbacks` has callbacks to create new object files and new symbol tables inside those object files. `struct gdb_unwind_callbacks` has callbacks to read registers off the current frame and to write out the values of the registers in the previous frame. Both have a callback (`target_read`) to read bytes off the target's address space.