blob: b46b4ec9fe422b19968aede5847fa8d589cda207 [file] [log] [blame]
# Copyright (C) 2024-2024 Free Software Foundation, Inc.
#
# This file is part of GDB.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
# This code is same (modulo small tweaks) as the code in documentation,
# section "JIT Interface in Python". If changed the documentation should
# be checked and updated accordingly if necessary.
import gdb
objfile = None
compunit = None
block = None
symtab = None
symbol = None
def get_linetable_entries(addr):
# Entries are not in increasing order to test that
# gdb.LineTable.__init__() sorts them properly.
return [
gdb.LineTableEntry(31, addr+6, True),
gdb.LineTableEntry(29, addr, True),
gdb.LineTableEntry(30, addr+3, True)
]
class JITRegisterCode(gdb.Breakpoint):
def stop(self):
global objfile
global compunit
global block
global symtab
global symbol
frame = gdb.newest_frame()
name = frame.read_var('name').string()
addr = int(frame.read_var('code'))
size = int(frame.read_var('size'))
linetable_entries = get_linetable_entries(addr)
# Create objfile and compunit for allocated "jit" code
objfile = gdb.Objfile(name)
compunit = gdb.Compunit(name, objfile, addr, addr + size)
# Mark the objfile as "jitted code". This will be used later when
# unregistering discarded code to check the objfile was indeed
# created for jitted code.
setattr(objfile, "is_jit_code", True)
# Create block for jitted function
block = gdb.Block(compunit.static_block(), addr, addr + size)
# Create symbol table holding info about jitted function, ...
symtab = gdb.Symtab("py-jit.c", compunit)
linetable = gdb.LineTable(symtab, linetable_entries)
# ...type of the jitted function...
int64_t = gdb.selected_inferior().architecture().integer_type(64)
func_t = int64_t.function(int64_t, int64_t)
# ...and symbol representing jitted function.
symbol = gdb.Symbol(name, symtab, func_t,
gdb.SYMBOL_FUNCTION_DOMAIN, gdb.SYMBOL_LOC_BLOCK,
block)
# Finally, register the symbol in static block
compunit.static_block().add_symbol(symbol)
return False # Continue execution
# Create breakpoint to register new code
JITRegisterCode("jit_register_code", internal=True)
class JITUnregisterCode(gdb.Breakpoint):
def stop(self):
frame = gdb.newest_frame()
addr = int(frame.read_var('code'))
objfile = gdb.current_progspace().objfile_for_address(addr)
if objfile is None:
# No objfile for given addr - bail out (this should not happen)
assert False
return False # Continue execution
if not getattr(objfile, "is_jit_code", False):
# Not a jitted addr - bail out (this should not happen either)
assert False
return False # Continue execution
# Remove the objfile and all debug info associated with it.
objfile.unlink()
return False # Continue execution
# Create breakpoint to discard old code
JITUnregisterCode("jit_unregister_code", internal=True)