2018-01-01 05:43:02 +01:00
|
|
|
/* Copyright (C) 2009-2018 Free Software Foundation, Inc.
|
2016-06-17 20:24:08 +02:00
|
|
|
|
|
|
|
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/>. */
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include JIT_READER_H /* Please see jit-reader.exp for an explanation. */
|
|
|
|
#include "jithost.h"
|
|
|
|
|
|
|
|
GDB_DECLARE_GPL_COMPATIBLE_READER;
|
|
|
|
|
|
|
|
enum register_mapping
|
|
|
|
{
|
|
|
|
AMD64_RA = 16,
|
Extend JIT-reader test and fix GDB problems that exposes
The jit-reader.exp test isn't really exercising the jit-reader's
unwinder API at all. This commit address that, and then fixes GDB
problems exposed.
- The custom JIT reader provided for the jit-reader.exp testcase
always rejects the jitted function's frame...
This is because the custom JIT reader in the testcase never ever
sets state->code_begin/end, so the bounds check in
gdb.base/jitreader.c:unwind_frame:
if (this_ip >= state->code_end || this_ip < state->code_begin)
return GDB_FAIL;
tends to fail, unless you're "lucky" (because it references
uninitialized data).
The result is that GDB is always actually using a built-in unwinder
for the jitted function.
- The provided unwinder doesn't do anything that GDB's built-in
unwinder can't do.
IOW, we can't really tell whether the JIT reader's unwinder is
working or not.
I fixed that by making the jitted function mangle its own stack
pointer with a xor, and then teaching the jit unwinder to demangle
it back (another xor). So now "backtrace" with GDB's built-in
unwinder fails while with the jit unwinder, it succeeds.
- GDB crashes after unloading the JIT reader, and flushing frames...
I made the testcase use the "flushregs" command after unloading the
JIT reader, to force the JIT frames to be flushed. However, that
crashes GDB...
When reinit_frame_cache tears down a frame's cache, it calls its
unwinder's dealloc_cache method, which for JIT frames ends up in
jit.c:jit_dealloc_cache. This function calls each of the frame's
gdb_reg_value's "free" pointer:
for (i = 0; i < gdbarch_num_regs (frame_arch); i++)
if (priv_data->registers[i] && priv_data->registers[i]->free)
priv_data->registers[i]->free (priv_data->registers[i]);
and the problem is these gdb_reg_value instances have been returned
by the JIT reader that has been already unloaded, and their "free"
function pointers likely point to functions in the DSO that has
already been unloaded...
A fix for that could be to call reinit_frame_cache in
jit_reader_unload_command _before_ unloading the jit reader DSO so
that the jit reader is given a chance to clean up the gdb_reg_values
before it is unloaded. However, the fix for the point below makes
this unnecessary, because it stops jit.c from keeping around
gdb_reg_values in the first place.
- However, it still makes sense to clear the frame cache when loading
or unloading a JIT unwinder.
This makes testing a JIT unwinder a bit simpler.
- Not only the frame cache actually -- gdb is not unloading the
jit-registered objfiles when the JIT reader is unloaded, and not
loading the already-registered descriptors when a JIT reader is
loaded.
The new test exercises unloading the jit reader, loading it back
again, and then making sure the JIT reader's unwinder works again.
Without the unload/re-load of already-read descriptors, the newly
loaded JIT would have no idea where the new function is, because
it's stored at symbol read time.
- I added a couple "info frame" calls to the test, and that
crashes GDB...
The problem is that jit_frame_prev_register assumes it'll only be
called for raw registers, so when it gets a pseudo register number,
the "priv->registers[reg]" access is really an out-of-bounds access.
To fix that, I made jit_frame_prev_register use
gdbarch_pseudo_register_read_value for reading the pseudo-registers.
However, that works with a regcache and we don't have one. To fix
that, I made the JIT unwinder store a regcache in its cache instead
of an array of gdb_reg_value pointers.
gdb/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* jit.c (jit_reader_load_command): Call reinit_frame_cache and
jit_inferior_created_hook.
(jit_reader_unload_command): Call reinit_frame_cache and
jit_inferior_exit_hook.
* jit.c (struct jit_unwind_private) <registers>: Delete field.
<regcache>: New field.
(jit_unwind_reg_set_impl): Set the register's value in the
regcache. Free the passed-in gdb_reg_value.
(jit_dealloc_cache): Adjust to free the regcache.
(jit_frame_sniffer): Allocate a regcache instead of an array of
gdb_reg_value pointers.
(jit_frame_this_id): Adjust.
(jit_frame_prev_register): Read raw registers off of the regcache
instead of from the gdb_reg_value pointer array. Use
gdbarch_pseudo_register_read_value to read pseudo registers.
* regcache.c (regcache_raw_set_cached_value): New function,
factored out from ...
(regcache_raw_write): ... here.
* regcache.h (regcache_raw_set_cached_value): Declare.
gdb/testsuite/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
* gdb.base/jit-reader.exp (info_registers_current_frame): New
procedure.
(jit_reader_test): Test the jit reader's unwinder.
* gdb.base/jithost.c (jit_function_00_code): New global.
(main): Use memcpy to fill in the mmapped code, instead of poking
bytes manually here.
* gdb.base/jitreader.c (enum register_mapping) <AMD64_RBP>: New
value.
(read_debug_info): Save the function's range.
(read_sp): New function.
(unwind_frame): Use it. Also unwind RBP.
(get_frame_id): Use read_sp.
(gdb_init_reader): Use calloc instead of malloc.
* lib/gdb.exp (get_hexadecimal_valueof): Add optional 'test'
parameter. Use gdb_test_multiple.
2016-07-01 12:56:39 +02:00
|
|
|
AMD64_RBP = 6,
|
2016-06-17 20:24:08 +02:00
|
|
|
AMD64_RSP = 7,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct reader_state
|
|
|
|
{
|
|
|
|
uintptr_t code_begin;
|
|
|
|
uintptr_t code_end;
|
|
|
|
};
|
|
|
|
|
|
|
|
static enum gdb_status
|
|
|
|
read_debug_info (struct gdb_reader_funcs *self,
|
|
|
|
struct gdb_symbol_callbacks *cbs,
|
|
|
|
void *memory, long memory_sz)
|
|
|
|
{
|
|
|
|
struct jithost_abi *symfile = memory;
|
|
|
|
struct gdb_object *object = cbs->object_open (cbs);
|
|
|
|
struct gdb_symtab *symtab = cbs->symtab_open (cbs, object, "");
|
|
|
|
GDB_CORE_ADDR begin = (GDB_CORE_ADDR) symfile->begin;
|
|
|
|
GDB_CORE_ADDR end = (GDB_CORE_ADDR) symfile->end;
|
Extend JIT-reader test and fix GDB problems that exposes
The jit-reader.exp test isn't really exercising the jit-reader's
unwinder API at all. This commit address that, and then fixes GDB
problems exposed.
- The custom JIT reader provided for the jit-reader.exp testcase
always rejects the jitted function's frame...
This is because the custom JIT reader in the testcase never ever
sets state->code_begin/end, so the bounds check in
gdb.base/jitreader.c:unwind_frame:
if (this_ip >= state->code_end || this_ip < state->code_begin)
return GDB_FAIL;
tends to fail, unless you're "lucky" (because it references
uninitialized data).
The result is that GDB is always actually using a built-in unwinder
for the jitted function.
- The provided unwinder doesn't do anything that GDB's built-in
unwinder can't do.
IOW, we can't really tell whether the JIT reader's unwinder is
working or not.
I fixed that by making the jitted function mangle its own stack
pointer with a xor, and then teaching the jit unwinder to demangle
it back (another xor). So now "backtrace" with GDB's built-in
unwinder fails while with the jit unwinder, it succeeds.
- GDB crashes after unloading the JIT reader, and flushing frames...
I made the testcase use the "flushregs" command after unloading the
JIT reader, to force the JIT frames to be flushed. However, that
crashes GDB...
When reinit_frame_cache tears down a frame's cache, it calls its
unwinder's dealloc_cache method, which for JIT frames ends up in
jit.c:jit_dealloc_cache. This function calls each of the frame's
gdb_reg_value's "free" pointer:
for (i = 0; i < gdbarch_num_regs (frame_arch); i++)
if (priv_data->registers[i] && priv_data->registers[i]->free)
priv_data->registers[i]->free (priv_data->registers[i]);
and the problem is these gdb_reg_value instances have been returned
by the JIT reader that has been already unloaded, and their "free"
function pointers likely point to functions in the DSO that has
already been unloaded...
A fix for that could be to call reinit_frame_cache in
jit_reader_unload_command _before_ unloading the jit reader DSO so
that the jit reader is given a chance to clean up the gdb_reg_values
before it is unloaded. However, the fix for the point below makes
this unnecessary, because it stops jit.c from keeping around
gdb_reg_values in the first place.
- However, it still makes sense to clear the frame cache when loading
or unloading a JIT unwinder.
This makes testing a JIT unwinder a bit simpler.
- Not only the frame cache actually -- gdb is not unloading the
jit-registered objfiles when the JIT reader is unloaded, and not
loading the already-registered descriptors when a JIT reader is
loaded.
The new test exercises unloading the jit reader, loading it back
again, and then making sure the JIT reader's unwinder works again.
Without the unload/re-load of already-read descriptors, the newly
loaded JIT would have no idea where the new function is, because
it's stored at symbol read time.
- I added a couple "info frame" calls to the test, and that
crashes GDB...
The problem is that jit_frame_prev_register assumes it'll only be
called for raw registers, so when it gets a pseudo register number,
the "priv->registers[reg]" access is really an out-of-bounds access.
To fix that, I made jit_frame_prev_register use
gdbarch_pseudo_register_read_value for reading the pseudo-registers.
However, that works with a regcache and we don't have one. To fix
that, I made the JIT unwinder store a regcache in its cache instead
of an array of gdb_reg_value pointers.
gdb/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* jit.c (jit_reader_load_command): Call reinit_frame_cache and
jit_inferior_created_hook.
(jit_reader_unload_command): Call reinit_frame_cache and
jit_inferior_exit_hook.
* jit.c (struct jit_unwind_private) <registers>: Delete field.
<regcache>: New field.
(jit_unwind_reg_set_impl): Set the register's value in the
regcache. Free the passed-in gdb_reg_value.
(jit_dealloc_cache): Adjust to free the regcache.
(jit_frame_sniffer): Allocate a regcache instead of an array of
gdb_reg_value pointers.
(jit_frame_this_id): Adjust.
(jit_frame_prev_register): Read raw registers off of the regcache
instead of from the gdb_reg_value pointer array. Use
gdbarch_pseudo_register_read_value to read pseudo registers.
* regcache.c (regcache_raw_set_cached_value): New function,
factored out from ...
(regcache_raw_write): ... here.
* regcache.h (regcache_raw_set_cached_value): Declare.
gdb/testsuite/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
* gdb.base/jit-reader.exp (info_registers_current_frame): New
procedure.
(jit_reader_test): Test the jit reader's unwinder.
* gdb.base/jithost.c (jit_function_00_code): New global.
(main): Use memcpy to fill in the mmapped code, instead of poking
bytes manually here.
* gdb.base/jitreader.c (enum register_mapping) <AMD64_RBP>: New
value.
(read_debug_info): Save the function's range.
(read_sp): New function.
(unwind_frame): Use it. Also unwind RBP.
(get_frame_id): Use read_sp.
(gdb_init_reader): Use calloc instead of malloc.
* lib/gdb.exp (get_hexadecimal_valueof): Add optional 'test'
parameter. Use gdb_test_multiple.
2016-07-01 12:56:39 +02:00
|
|
|
struct reader_state *state = (struct reader_state *) self->priv_data;
|
|
|
|
|
|
|
|
/* Record the function's range, for the unwinder. */
|
|
|
|
state->code_begin = begin;
|
|
|
|
state->code_end = end;
|
2016-06-17 20:24:08 +02:00
|
|
|
|
|
|
|
cbs->block_open (cbs, symtab, NULL, begin, end, "jit_function_00");
|
|
|
|
|
|
|
|
cbs->symtab_close (cbs, symtab);
|
|
|
|
cbs->object_close (cbs, object);
|
|
|
|
return GDB_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
free_reg_value (struct gdb_reg_value *value)
|
|
|
|
{
|
|
|
|
free (value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
write_register (struct gdb_unwind_callbacks *callbacks, int dw_reg,
|
|
|
|
uintptr_t value)
|
|
|
|
{
|
|
|
|
const int size = sizeof (uintptr_t);
|
|
|
|
struct gdb_reg_value *reg_val =
|
|
|
|
malloc (sizeof (struct gdb_reg_value) + size - 1);
|
|
|
|
reg_val->defined = 1;
|
|
|
|
reg_val->free = free_reg_value;
|
|
|
|
|
|
|
|
memcpy (reg_val->value, &value, size);
|
|
|
|
callbacks->reg_set (callbacks, dw_reg, reg_val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
read_register (struct gdb_unwind_callbacks *callbacks, int dw_reg,
|
|
|
|
uintptr_t *value)
|
|
|
|
{
|
|
|
|
const int size = sizeof (uintptr_t);
|
|
|
|
struct gdb_reg_value *reg_val = callbacks->reg_get (callbacks, dw_reg);
|
|
|
|
if (reg_val->size != size || !reg_val->defined)
|
|
|
|
{
|
|
|
|
reg_val->free (reg_val);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
memcpy (value, reg_val->value, size);
|
|
|
|
reg_val->free (reg_val);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
Extend JIT-reader test and fix GDB problems that exposes
The jit-reader.exp test isn't really exercising the jit-reader's
unwinder API at all. This commit address that, and then fixes GDB
problems exposed.
- The custom JIT reader provided for the jit-reader.exp testcase
always rejects the jitted function's frame...
This is because the custom JIT reader in the testcase never ever
sets state->code_begin/end, so the bounds check in
gdb.base/jitreader.c:unwind_frame:
if (this_ip >= state->code_end || this_ip < state->code_begin)
return GDB_FAIL;
tends to fail, unless you're "lucky" (because it references
uninitialized data).
The result is that GDB is always actually using a built-in unwinder
for the jitted function.
- The provided unwinder doesn't do anything that GDB's built-in
unwinder can't do.
IOW, we can't really tell whether the JIT reader's unwinder is
working or not.
I fixed that by making the jitted function mangle its own stack
pointer with a xor, and then teaching the jit unwinder to demangle
it back (another xor). So now "backtrace" with GDB's built-in
unwinder fails while with the jit unwinder, it succeeds.
- GDB crashes after unloading the JIT reader, and flushing frames...
I made the testcase use the "flushregs" command after unloading the
JIT reader, to force the JIT frames to be flushed. However, that
crashes GDB...
When reinit_frame_cache tears down a frame's cache, it calls its
unwinder's dealloc_cache method, which for JIT frames ends up in
jit.c:jit_dealloc_cache. This function calls each of the frame's
gdb_reg_value's "free" pointer:
for (i = 0; i < gdbarch_num_regs (frame_arch); i++)
if (priv_data->registers[i] && priv_data->registers[i]->free)
priv_data->registers[i]->free (priv_data->registers[i]);
and the problem is these gdb_reg_value instances have been returned
by the JIT reader that has been already unloaded, and their "free"
function pointers likely point to functions in the DSO that has
already been unloaded...
A fix for that could be to call reinit_frame_cache in
jit_reader_unload_command _before_ unloading the jit reader DSO so
that the jit reader is given a chance to clean up the gdb_reg_values
before it is unloaded. However, the fix for the point below makes
this unnecessary, because it stops jit.c from keeping around
gdb_reg_values in the first place.
- However, it still makes sense to clear the frame cache when loading
or unloading a JIT unwinder.
This makes testing a JIT unwinder a bit simpler.
- Not only the frame cache actually -- gdb is not unloading the
jit-registered objfiles when the JIT reader is unloaded, and not
loading the already-registered descriptors when a JIT reader is
loaded.
The new test exercises unloading the jit reader, loading it back
again, and then making sure the JIT reader's unwinder works again.
Without the unload/re-load of already-read descriptors, the newly
loaded JIT would have no idea where the new function is, because
it's stored at symbol read time.
- I added a couple "info frame" calls to the test, and that
crashes GDB...
The problem is that jit_frame_prev_register assumes it'll only be
called for raw registers, so when it gets a pseudo register number,
the "priv->registers[reg]" access is really an out-of-bounds access.
To fix that, I made jit_frame_prev_register use
gdbarch_pseudo_register_read_value for reading the pseudo-registers.
However, that works with a regcache and we don't have one. To fix
that, I made the JIT unwinder store a regcache in its cache instead
of an array of gdb_reg_value pointers.
gdb/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* jit.c (jit_reader_load_command): Call reinit_frame_cache and
jit_inferior_created_hook.
(jit_reader_unload_command): Call reinit_frame_cache and
jit_inferior_exit_hook.
* jit.c (struct jit_unwind_private) <registers>: Delete field.
<regcache>: New field.
(jit_unwind_reg_set_impl): Set the register's value in the
regcache. Free the passed-in gdb_reg_value.
(jit_dealloc_cache): Adjust to free the regcache.
(jit_frame_sniffer): Allocate a regcache instead of an array of
gdb_reg_value pointers.
(jit_frame_this_id): Adjust.
(jit_frame_prev_register): Read raw registers off of the regcache
instead of from the gdb_reg_value pointer array. Use
gdbarch_pseudo_register_read_value to read pseudo registers.
* regcache.c (regcache_raw_set_cached_value): New function,
factored out from ...
(regcache_raw_write): ... here.
* regcache.h (regcache_raw_set_cached_value): Declare.
gdb/testsuite/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
* gdb.base/jit-reader.exp (info_registers_current_frame): New
procedure.
(jit_reader_test): Test the jit reader's unwinder.
* gdb.base/jithost.c (jit_function_00_code): New global.
(main): Use memcpy to fill in the mmapped code, instead of poking
bytes manually here.
* gdb.base/jitreader.c (enum register_mapping) <AMD64_RBP>: New
value.
(read_debug_info): Save the function's range.
(read_sp): New function.
(unwind_frame): Use it. Also unwind RBP.
(get_frame_id): Use read_sp.
(gdb_init_reader): Use calloc instead of malloc.
* lib/gdb.exp (get_hexadecimal_valueof): Add optional 'test'
parameter. Use gdb_test_multiple.
2016-07-01 12:56:39 +02:00
|
|
|
/* Read the stack pointer into *VALUE. IP is the address the inferior
|
|
|
|
is currently stopped at. Takes care of demangling the stack
|
|
|
|
pointer if necessary. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
read_sp (struct gdb_reader_funcs *self, struct gdb_unwind_callbacks *cbs,
|
|
|
|
uintptr_t ip, uintptr_t *value)
|
|
|
|
{
|
|
|
|
struct reader_state *state = (struct reader_state *) self->priv_data;
|
|
|
|
uintptr_t sp;
|
|
|
|
|
|
|
|
if (!read_register (cbs, AMD64_RSP, &sp))
|
|
|
|
return GDB_FAIL;
|
|
|
|
|
|
|
|
/* If stopped at the instruction after the "xor $-1, %rsp", demangle
|
|
|
|
the stack pointer back. */
|
|
|
|
if (ip == state->code_begin + 5)
|
|
|
|
sp ^= (uintptr_t) -1;
|
|
|
|
|
|
|
|
*value = sp;
|
|
|
|
return GDB_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-06-17 20:24:08 +02:00
|
|
|
static enum gdb_status
|
|
|
|
unwind_frame (struct gdb_reader_funcs *self, struct gdb_unwind_callbacks *cbs)
|
|
|
|
{
|
|
|
|
const int word_size = sizeof (uintptr_t);
|
Extend JIT-reader test and fix GDB problems that exposes
The jit-reader.exp test isn't really exercising the jit-reader's
unwinder API at all. This commit address that, and then fixes GDB
problems exposed.
- The custom JIT reader provided for the jit-reader.exp testcase
always rejects the jitted function's frame...
This is because the custom JIT reader in the testcase never ever
sets state->code_begin/end, so the bounds check in
gdb.base/jitreader.c:unwind_frame:
if (this_ip >= state->code_end || this_ip < state->code_begin)
return GDB_FAIL;
tends to fail, unless you're "lucky" (because it references
uninitialized data).
The result is that GDB is always actually using a built-in unwinder
for the jitted function.
- The provided unwinder doesn't do anything that GDB's built-in
unwinder can't do.
IOW, we can't really tell whether the JIT reader's unwinder is
working or not.
I fixed that by making the jitted function mangle its own stack
pointer with a xor, and then teaching the jit unwinder to demangle
it back (another xor). So now "backtrace" with GDB's built-in
unwinder fails while with the jit unwinder, it succeeds.
- GDB crashes after unloading the JIT reader, and flushing frames...
I made the testcase use the "flushregs" command after unloading the
JIT reader, to force the JIT frames to be flushed. However, that
crashes GDB...
When reinit_frame_cache tears down a frame's cache, it calls its
unwinder's dealloc_cache method, which for JIT frames ends up in
jit.c:jit_dealloc_cache. This function calls each of the frame's
gdb_reg_value's "free" pointer:
for (i = 0; i < gdbarch_num_regs (frame_arch); i++)
if (priv_data->registers[i] && priv_data->registers[i]->free)
priv_data->registers[i]->free (priv_data->registers[i]);
and the problem is these gdb_reg_value instances have been returned
by the JIT reader that has been already unloaded, and their "free"
function pointers likely point to functions in the DSO that has
already been unloaded...
A fix for that could be to call reinit_frame_cache in
jit_reader_unload_command _before_ unloading the jit reader DSO so
that the jit reader is given a chance to clean up the gdb_reg_values
before it is unloaded. However, the fix for the point below makes
this unnecessary, because it stops jit.c from keeping around
gdb_reg_values in the first place.
- However, it still makes sense to clear the frame cache when loading
or unloading a JIT unwinder.
This makes testing a JIT unwinder a bit simpler.
- Not only the frame cache actually -- gdb is not unloading the
jit-registered objfiles when the JIT reader is unloaded, and not
loading the already-registered descriptors when a JIT reader is
loaded.
The new test exercises unloading the jit reader, loading it back
again, and then making sure the JIT reader's unwinder works again.
Without the unload/re-load of already-read descriptors, the newly
loaded JIT would have no idea where the new function is, because
it's stored at symbol read time.
- I added a couple "info frame" calls to the test, and that
crashes GDB...
The problem is that jit_frame_prev_register assumes it'll only be
called for raw registers, so when it gets a pseudo register number,
the "priv->registers[reg]" access is really an out-of-bounds access.
To fix that, I made jit_frame_prev_register use
gdbarch_pseudo_register_read_value for reading the pseudo-registers.
However, that works with a regcache and we don't have one. To fix
that, I made the JIT unwinder store a regcache in its cache instead
of an array of gdb_reg_value pointers.
gdb/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* jit.c (jit_reader_load_command): Call reinit_frame_cache and
jit_inferior_created_hook.
(jit_reader_unload_command): Call reinit_frame_cache and
jit_inferior_exit_hook.
* jit.c (struct jit_unwind_private) <registers>: Delete field.
<regcache>: New field.
(jit_unwind_reg_set_impl): Set the register's value in the
regcache. Free the passed-in gdb_reg_value.
(jit_dealloc_cache): Adjust to free the regcache.
(jit_frame_sniffer): Allocate a regcache instead of an array of
gdb_reg_value pointers.
(jit_frame_this_id): Adjust.
(jit_frame_prev_register): Read raw registers off of the regcache
instead of from the gdb_reg_value pointer array. Use
gdbarch_pseudo_register_read_value to read pseudo registers.
* regcache.c (regcache_raw_set_cached_value): New function,
factored out from ...
(regcache_raw_write): ... here.
* regcache.h (regcache_raw_set_cached_value): Declare.
gdb/testsuite/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
* gdb.base/jit-reader.exp (info_registers_current_frame): New
procedure.
(jit_reader_test): Test the jit reader's unwinder.
* gdb.base/jithost.c (jit_function_00_code): New global.
(main): Use memcpy to fill in the mmapped code, instead of poking
bytes manually here.
* gdb.base/jitreader.c (enum register_mapping) <AMD64_RBP>: New
value.
(read_debug_info): Save the function's range.
(read_sp): New function.
(unwind_frame): Use it. Also unwind RBP.
(get_frame_id): Use read_sp.
(gdb_init_reader): Use calloc instead of malloc.
* lib/gdb.exp (get_hexadecimal_valueof): Add optional 'test'
parameter. Use gdb_test_multiple.
2016-07-01 12:56:39 +02:00
|
|
|
uintptr_t prev_sp, this_sp;
|
|
|
|
uintptr_t prev_ip, this_ip;
|
|
|
|
uintptr_t prev_bp, this_bp;
|
2016-06-17 20:24:08 +02:00
|
|
|
struct reader_state *state = (struct reader_state *) self->priv_data;
|
|
|
|
|
|
|
|
if (!read_register (cbs, AMD64_RA, &this_ip))
|
|
|
|
return GDB_FAIL;
|
|
|
|
|
|
|
|
if (this_ip >= state->code_end || this_ip < state->code_begin)
|
|
|
|
return GDB_FAIL;
|
|
|
|
|
Extend JIT-reader test and fix GDB problems that exposes
The jit-reader.exp test isn't really exercising the jit-reader's
unwinder API at all. This commit address that, and then fixes GDB
problems exposed.
- The custom JIT reader provided for the jit-reader.exp testcase
always rejects the jitted function's frame...
This is because the custom JIT reader in the testcase never ever
sets state->code_begin/end, so the bounds check in
gdb.base/jitreader.c:unwind_frame:
if (this_ip >= state->code_end || this_ip < state->code_begin)
return GDB_FAIL;
tends to fail, unless you're "lucky" (because it references
uninitialized data).
The result is that GDB is always actually using a built-in unwinder
for the jitted function.
- The provided unwinder doesn't do anything that GDB's built-in
unwinder can't do.
IOW, we can't really tell whether the JIT reader's unwinder is
working or not.
I fixed that by making the jitted function mangle its own stack
pointer with a xor, and then teaching the jit unwinder to demangle
it back (another xor). So now "backtrace" with GDB's built-in
unwinder fails while with the jit unwinder, it succeeds.
- GDB crashes after unloading the JIT reader, and flushing frames...
I made the testcase use the "flushregs" command after unloading the
JIT reader, to force the JIT frames to be flushed. However, that
crashes GDB...
When reinit_frame_cache tears down a frame's cache, it calls its
unwinder's dealloc_cache method, which for JIT frames ends up in
jit.c:jit_dealloc_cache. This function calls each of the frame's
gdb_reg_value's "free" pointer:
for (i = 0; i < gdbarch_num_regs (frame_arch); i++)
if (priv_data->registers[i] && priv_data->registers[i]->free)
priv_data->registers[i]->free (priv_data->registers[i]);
and the problem is these gdb_reg_value instances have been returned
by the JIT reader that has been already unloaded, and their "free"
function pointers likely point to functions in the DSO that has
already been unloaded...
A fix for that could be to call reinit_frame_cache in
jit_reader_unload_command _before_ unloading the jit reader DSO so
that the jit reader is given a chance to clean up the gdb_reg_values
before it is unloaded. However, the fix for the point below makes
this unnecessary, because it stops jit.c from keeping around
gdb_reg_values in the first place.
- However, it still makes sense to clear the frame cache when loading
or unloading a JIT unwinder.
This makes testing a JIT unwinder a bit simpler.
- Not only the frame cache actually -- gdb is not unloading the
jit-registered objfiles when the JIT reader is unloaded, and not
loading the already-registered descriptors when a JIT reader is
loaded.
The new test exercises unloading the jit reader, loading it back
again, and then making sure the JIT reader's unwinder works again.
Without the unload/re-load of already-read descriptors, the newly
loaded JIT would have no idea where the new function is, because
it's stored at symbol read time.
- I added a couple "info frame" calls to the test, and that
crashes GDB...
The problem is that jit_frame_prev_register assumes it'll only be
called for raw registers, so when it gets a pseudo register number,
the "priv->registers[reg]" access is really an out-of-bounds access.
To fix that, I made jit_frame_prev_register use
gdbarch_pseudo_register_read_value for reading the pseudo-registers.
However, that works with a regcache and we don't have one. To fix
that, I made the JIT unwinder store a regcache in its cache instead
of an array of gdb_reg_value pointers.
gdb/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* jit.c (jit_reader_load_command): Call reinit_frame_cache and
jit_inferior_created_hook.
(jit_reader_unload_command): Call reinit_frame_cache and
jit_inferior_exit_hook.
* jit.c (struct jit_unwind_private) <registers>: Delete field.
<regcache>: New field.
(jit_unwind_reg_set_impl): Set the register's value in the
regcache. Free the passed-in gdb_reg_value.
(jit_dealloc_cache): Adjust to free the regcache.
(jit_frame_sniffer): Allocate a regcache instead of an array of
gdb_reg_value pointers.
(jit_frame_this_id): Adjust.
(jit_frame_prev_register): Read raw registers off of the regcache
instead of from the gdb_reg_value pointer array. Use
gdbarch_pseudo_register_read_value to read pseudo registers.
* regcache.c (regcache_raw_set_cached_value): New function,
factored out from ...
(regcache_raw_write): ... here.
* regcache.h (regcache_raw_set_cached_value): Declare.
gdb/testsuite/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
* gdb.base/jit-reader.exp (info_registers_current_frame): New
procedure.
(jit_reader_test): Test the jit reader's unwinder.
* gdb.base/jithost.c (jit_function_00_code): New global.
(main): Use memcpy to fill in the mmapped code, instead of poking
bytes manually here.
* gdb.base/jitreader.c (enum register_mapping) <AMD64_RBP>: New
value.
(read_debug_info): Save the function's range.
(read_sp): New function.
(unwind_frame): Use it. Also unwind RBP.
(get_frame_id): Use read_sp.
(gdb_init_reader): Use calloc instead of malloc.
* lib/gdb.exp (get_hexadecimal_valueof): Add optional 'test'
parameter. Use gdb_test_multiple.
2016-07-01 12:56:39 +02:00
|
|
|
/* Unwind RBP in order to make the unwinder that tries to unwind
|
|
|
|
from the just-unwound frame happy. */
|
|
|
|
if (!read_register (cbs, AMD64_RBP, &this_bp))
|
2016-06-17 20:24:08 +02:00
|
|
|
return GDB_FAIL;
|
Extend JIT-reader test and fix GDB problems that exposes
The jit-reader.exp test isn't really exercising the jit-reader's
unwinder API at all. This commit address that, and then fixes GDB
problems exposed.
- The custom JIT reader provided for the jit-reader.exp testcase
always rejects the jitted function's frame...
This is because the custom JIT reader in the testcase never ever
sets state->code_begin/end, so the bounds check in
gdb.base/jitreader.c:unwind_frame:
if (this_ip >= state->code_end || this_ip < state->code_begin)
return GDB_FAIL;
tends to fail, unless you're "lucky" (because it references
uninitialized data).
The result is that GDB is always actually using a built-in unwinder
for the jitted function.
- The provided unwinder doesn't do anything that GDB's built-in
unwinder can't do.
IOW, we can't really tell whether the JIT reader's unwinder is
working or not.
I fixed that by making the jitted function mangle its own stack
pointer with a xor, and then teaching the jit unwinder to demangle
it back (another xor). So now "backtrace" with GDB's built-in
unwinder fails while with the jit unwinder, it succeeds.
- GDB crashes after unloading the JIT reader, and flushing frames...
I made the testcase use the "flushregs" command after unloading the
JIT reader, to force the JIT frames to be flushed. However, that
crashes GDB...
When reinit_frame_cache tears down a frame's cache, it calls its
unwinder's dealloc_cache method, which for JIT frames ends up in
jit.c:jit_dealloc_cache. This function calls each of the frame's
gdb_reg_value's "free" pointer:
for (i = 0; i < gdbarch_num_regs (frame_arch); i++)
if (priv_data->registers[i] && priv_data->registers[i]->free)
priv_data->registers[i]->free (priv_data->registers[i]);
and the problem is these gdb_reg_value instances have been returned
by the JIT reader that has been already unloaded, and their "free"
function pointers likely point to functions in the DSO that has
already been unloaded...
A fix for that could be to call reinit_frame_cache in
jit_reader_unload_command _before_ unloading the jit reader DSO so
that the jit reader is given a chance to clean up the gdb_reg_values
before it is unloaded. However, the fix for the point below makes
this unnecessary, because it stops jit.c from keeping around
gdb_reg_values in the first place.
- However, it still makes sense to clear the frame cache when loading
or unloading a JIT unwinder.
This makes testing a JIT unwinder a bit simpler.
- Not only the frame cache actually -- gdb is not unloading the
jit-registered objfiles when the JIT reader is unloaded, and not
loading the already-registered descriptors when a JIT reader is
loaded.
The new test exercises unloading the jit reader, loading it back
again, and then making sure the JIT reader's unwinder works again.
Without the unload/re-load of already-read descriptors, the newly
loaded JIT would have no idea where the new function is, because
it's stored at symbol read time.
- I added a couple "info frame" calls to the test, and that
crashes GDB...
The problem is that jit_frame_prev_register assumes it'll only be
called for raw registers, so when it gets a pseudo register number,
the "priv->registers[reg]" access is really an out-of-bounds access.
To fix that, I made jit_frame_prev_register use
gdbarch_pseudo_register_read_value for reading the pseudo-registers.
However, that works with a regcache and we don't have one. To fix
that, I made the JIT unwinder store a regcache in its cache instead
of an array of gdb_reg_value pointers.
gdb/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* jit.c (jit_reader_load_command): Call reinit_frame_cache and
jit_inferior_created_hook.
(jit_reader_unload_command): Call reinit_frame_cache and
jit_inferior_exit_hook.
* jit.c (struct jit_unwind_private) <registers>: Delete field.
<regcache>: New field.
(jit_unwind_reg_set_impl): Set the register's value in the
regcache. Free the passed-in gdb_reg_value.
(jit_dealloc_cache): Adjust to free the regcache.
(jit_frame_sniffer): Allocate a regcache instead of an array of
gdb_reg_value pointers.
(jit_frame_this_id): Adjust.
(jit_frame_prev_register): Read raw registers off of the regcache
instead of from the gdb_reg_value pointer array. Use
gdbarch_pseudo_register_read_value to read pseudo registers.
* regcache.c (regcache_raw_set_cached_value): New function,
factored out from ...
(regcache_raw_write): ... here.
* regcache.h (regcache_raw_set_cached_value): Declare.
gdb/testsuite/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
* gdb.base/jit-reader.exp (info_registers_current_frame): New
procedure.
(jit_reader_test): Test the jit reader's unwinder.
* gdb.base/jithost.c (jit_function_00_code): New global.
(main): Use memcpy to fill in the mmapped code, instead of poking
bytes manually here.
* gdb.base/jitreader.c (enum register_mapping) <AMD64_RBP>: New
value.
(read_debug_info): Save the function's range.
(read_sp): New function.
(unwind_frame): Use it. Also unwind RBP.
(get_frame_id): Use read_sp.
(gdb_init_reader): Use calloc instead of malloc.
* lib/gdb.exp (get_hexadecimal_valueof): Add optional 'test'
parameter. Use gdb_test_multiple.
2016-07-01 12:56:39 +02:00
|
|
|
/* RBP is unmodified. */
|
|
|
|
prev_bp = this_bp;
|
2016-06-17 20:24:08 +02:00
|
|
|
|
Extend JIT-reader test and fix GDB problems that exposes
The jit-reader.exp test isn't really exercising the jit-reader's
unwinder API at all. This commit address that, and then fixes GDB
problems exposed.
- The custom JIT reader provided for the jit-reader.exp testcase
always rejects the jitted function's frame...
This is because the custom JIT reader in the testcase never ever
sets state->code_begin/end, so the bounds check in
gdb.base/jitreader.c:unwind_frame:
if (this_ip >= state->code_end || this_ip < state->code_begin)
return GDB_FAIL;
tends to fail, unless you're "lucky" (because it references
uninitialized data).
The result is that GDB is always actually using a built-in unwinder
for the jitted function.
- The provided unwinder doesn't do anything that GDB's built-in
unwinder can't do.
IOW, we can't really tell whether the JIT reader's unwinder is
working or not.
I fixed that by making the jitted function mangle its own stack
pointer with a xor, and then teaching the jit unwinder to demangle
it back (another xor). So now "backtrace" with GDB's built-in
unwinder fails while with the jit unwinder, it succeeds.
- GDB crashes after unloading the JIT reader, and flushing frames...
I made the testcase use the "flushregs" command after unloading the
JIT reader, to force the JIT frames to be flushed. However, that
crashes GDB...
When reinit_frame_cache tears down a frame's cache, it calls its
unwinder's dealloc_cache method, which for JIT frames ends up in
jit.c:jit_dealloc_cache. This function calls each of the frame's
gdb_reg_value's "free" pointer:
for (i = 0; i < gdbarch_num_regs (frame_arch); i++)
if (priv_data->registers[i] && priv_data->registers[i]->free)
priv_data->registers[i]->free (priv_data->registers[i]);
and the problem is these gdb_reg_value instances have been returned
by the JIT reader that has been already unloaded, and their "free"
function pointers likely point to functions in the DSO that has
already been unloaded...
A fix for that could be to call reinit_frame_cache in
jit_reader_unload_command _before_ unloading the jit reader DSO so
that the jit reader is given a chance to clean up the gdb_reg_values
before it is unloaded. However, the fix for the point below makes
this unnecessary, because it stops jit.c from keeping around
gdb_reg_values in the first place.
- However, it still makes sense to clear the frame cache when loading
or unloading a JIT unwinder.
This makes testing a JIT unwinder a bit simpler.
- Not only the frame cache actually -- gdb is not unloading the
jit-registered objfiles when the JIT reader is unloaded, and not
loading the already-registered descriptors when a JIT reader is
loaded.
The new test exercises unloading the jit reader, loading it back
again, and then making sure the JIT reader's unwinder works again.
Without the unload/re-load of already-read descriptors, the newly
loaded JIT would have no idea where the new function is, because
it's stored at symbol read time.
- I added a couple "info frame" calls to the test, and that
crashes GDB...
The problem is that jit_frame_prev_register assumes it'll only be
called for raw registers, so when it gets a pseudo register number,
the "priv->registers[reg]" access is really an out-of-bounds access.
To fix that, I made jit_frame_prev_register use
gdbarch_pseudo_register_read_value for reading the pseudo-registers.
However, that works with a regcache and we don't have one. To fix
that, I made the JIT unwinder store a regcache in its cache instead
of an array of gdb_reg_value pointers.
gdb/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* jit.c (jit_reader_load_command): Call reinit_frame_cache and
jit_inferior_created_hook.
(jit_reader_unload_command): Call reinit_frame_cache and
jit_inferior_exit_hook.
* jit.c (struct jit_unwind_private) <registers>: Delete field.
<regcache>: New field.
(jit_unwind_reg_set_impl): Set the register's value in the
regcache. Free the passed-in gdb_reg_value.
(jit_dealloc_cache): Adjust to free the regcache.
(jit_frame_sniffer): Allocate a regcache instead of an array of
gdb_reg_value pointers.
(jit_frame_this_id): Adjust.
(jit_frame_prev_register): Read raw registers off of the regcache
instead of from the gdb_reg_value pointer array. Use
gdbarch_pseudo_register_read_value to read pseudo registers.
* regcache.c (regcache_raw_set_cached_value): New function,
factored out from ...
(regcache_raw_write): ... here.
* regcache.h (regcache_raw_set_cached_value): Declare.
gdb/testsuite/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
* gdb.base/jit-reader.exp (info_registers_current_frame): New
procedure.
(jit_reader_test): Test the jit reader's unwinder.
* gdb.base/jithost.c (jit_function_00_code): New global.
(main): Use memcpy to fill in the mmapped code, instead of poking
bytes manually here.
* gdb.base/jitreader.c (enum register_mapping) <AMD64_RBP>: New
value.
(read_debug_info): Save the function's range.
(read_sp): New function.
(unwind_frame): Use it. Also unwind RBP.
(get_frame_id): Use read_sp.
(gdb_init_reader): Use calloc instead of malloc.
* lib/gdb.exp (get_hexadecimal_valueof): Add optional 'test'
parameter. Use gdb_test_multiple.
2016-07-01 12:56:39 +02:00
|
|
|
/* Fetch the demangled stack pointer. */
|
|
|
|
if (!read_sp (self, cbs, this_ip, &this_sp))
|
2016-06-17 20:24:08 +02:00
|
|
|
return GDB_FAIL;
|
|
|
|
|
Extend JIT-reader test and fix GDB problems that exposes
The jit-reader.exp test isn't really exercising the jit-reader's
unwinder API at all. This commit address that, and then fixes GDB
problems exposed.
- The custom JIT reader provided for the jit-reader.exp testcase
always rejects the jitted function's frame...
This is because the custom JIT reader in the testcase never ever
sets state->code_begin/end, so the bounds check in
gdb.base/jitreader.c:unwind_frame:
if (this_ip >= state->code_end || this_ip < state->code_begin)
return GDB_FAIL;
tends to fail, unless you're "lucky" (because it references
uninitialized data).
The result is that GDB is always actually using a built-in unwinder
for the jitted function.
- The provided unwinder doesn't do anything that GDB's built-in
unwinder can't do.
IOW, we can't really tell whether the JIT reader's unwinder is
working or not.
I fixed that by making the jitted function mangle its own stack
pointer with a xor, and then teaching the jit unwinder to demangle
it back (another xor). So now "backtrace" with GDB's built-in
unwinder fails while with the jit unwinder, it succeeds.
- GDB crashes after unloading the JIT reader, and flushing frames...
I made the testcase use the "flushregs" command after unloading the
JIT reader, to force the JIT frames to be flushed. However, that
crashes GDB...
When reinit_frame_cache tears down a frame's cache, it calls its
unwinder's dealloc_cache method, which for JIT frames ends up in
jit.c:jit_dealloc_cache. This function calls each of the frame's
gdb_reg_value's "free" pointer:
for (i = 0; i < gdbarch_num_regs (frame_arch); i++)
if (priv_data->registers[i] && priv_data->registers[i]->free)
priv_data->registers[i]->free (priv_data->registers[i]);
and the problem is these gdb_reg_value instances have been returned
by the JIT reader that has been already unloaded, and their "free"
function pointers likely point to functions in the DSO that has
already been unloaded...
A fix for that could be to call reinit_frame_cache in
jit_reader_unload_command _before_ unloading the jit reader DSO so
that the jit reader is given a chance to clean up the gdb_reg_values
before it is unloaded. However, the fix for the point below makes
this unnecessary, because it stops jit.c from keeping around
gdb_reg_values in the first place.
- However, it still makes sense to clear the frame cache when loading
or unloading a JIT unwinder.
This makes testing a JIT unwinder a bit simpler.
- Not only the frame cache actually -- gdb is not unloading the
jit-registered objfiles when the JIT reader is unloaded, and not
loading the already-registered descriptors when a JIT reader is
loaded.
The new test exercises unloading the jit reader, loading it back
again, and then making sure the JIT reader's unwinder works again.
Without the unload/re-load of already-read descriptors, the newly
loaded JIT would have no idea where the new function is, because
it's stored at symbol read time.
- I added a couple "info frame" calls to the test, and that
crashes GDB...
The problem is that jit_frame_prev_register assumes it'll only be
called for raw registers, so when it gets a pseudo register number,
the "priv->registers[reg]" access is really an out-of-bounds access.
To fix that, I made jit_frame_prev_register use
gdbarch_pseudo_register_read_value for reading the pseudo-registers.
However, that works with a regcache and we don't have one. To fix
that, I made the JIT unwinder store a regcache in its cache instead
of an array of gdb_reg_value pointers.
gdb/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* jit.c (jit_reader_load_command): Call reinit_frame_cache and
jit_inferior_created_hook.
(jit_reader_unload_command): Call reinit_frame_cache and
jit_inferior_exit_hook.
* jit.c (struct jit_unwind_private) <registers>: Delete field.
<regcache>: New field.
(jit_unwind_reg_set_impl): Set the register's value in the
regcache. Free the passed-in gdb_reg_value.
(jit_dealloc_cache): Adjust to free the regcache.
(jit_frame_sniffer): Allocate a regcache instead of an array of
gdb_reg_value pointers.
(jit_frame_this_id): Adjust.
(jit_frame_prev_register): Read raw registers off of the regcache
instead of from the gdb_reg_value pointer array. Use
gdbarch_pseudo_register_read_value to read pseudo registers.
* regcache.c (regcache_raw_set_cached_value): New function,
factored out from ...
(regcache_raw_write): ... here.
* regcache.h (regcache_raw_set_cached_value): Declare.
gdb/testsuite/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
* gdb.base/jit-reader.exp (info_registers_current_frame): New
procedure.
(jit_reader_test): Test the jit reader's unwinder.
* gdb.base/jithost.c (jit_function_00_code): New global.
(main): Use memcpy to fill in the mmapped code, instead of poking
bytes manually here.
* gdb.base/jitreader.c (enum register_mapping) <AMD64_RBP>: New
value.
(read_debug_info): Save the function's range.
(read_sp): New function.
(unwind_frame): Use it. Also unwind RBP.
(get_frame_id): Use read_sp.
(gdb_init_reader): Use calloc instead of malloc.
* lib/gdb.exp (get_hexadecimal_valueof): Add optional 'test'
parameter. Use gdb_test_multiple.
2016-07-01 12:56:39 +02:00
|
|
|
/* The return address is saved on the stack. */
|
|
|
|
if (cbs->target_read (this_sp, &prev_ip, word_size) == GDB_FAIL)
|
|
|
|
return GDB_FAIL;
|
2016-06-17 20:24:08 +02:00
|
|
|
prev_sp = this_sp + word_size;
|
Extend JIT-reader test and fix GDB problems that exposes
The jit-reader.exp test isn't really exercising the jit-reader's
unwinder API at all. This commit address that, and then fixes GDB
problems exposed.
- The custom JIT reader provided for the jit-reader.exp testcase
always rejects the jitted function's frame...
This is because the custom JIT reader in the testcase never ever
sets state->code_begin/end, so the bounds check in
gdb.base/jitreader.c:unwind_frame:
if (this_ip >= state->code_end || this_ip < state->code_begin)
return GDB_FAIL;
tends to fail, unless you're "lucky" (because it references
uninitialized data).
The result is that GDB is always actually using a built-in unwinder
for the jitted function.
- The provided unwinder doesn't do anything that GDB's built-in
unwinder can't do.
IOW, we can't really tell whether the JIT reader's unwinder is
working or not.
I fixed that by making the jitted function mangle its own stack
pointer with a xor, and then teaching the jit unwinder to demangle
it back (another xor). So now "backtrace" with GDB's built-in
unwinder fails while with the jit unwinder, it succeeds.
- GDB crashes after unloading the JIT reader, and flushing frames...
I made the testcase use the "flushregs" command after unloading the
JIT reader, to force the JIT frames to be flushed. However, that
crashes GDB...
When reinit_frame_cache tears down a frame's cache, it calls its
unwinder's dealloc_cache method, which for JIT frames ends up in
jit.c:jit_dealloc_cache. This function calls each of the frame's
gdb_reg_value's "free" pointer:
for (i = 0; i < gdbarch_num_regs (frame_arch); i++)
if (priv_data->registers[i] && priv_data->registers[i]->free)
priv_data->registers[i]->free (priv_data->registers[i]);
and the problem is these gdb_reg_value instances have been returned
by the JIT reader that has been already unloaded, and their "free"
function pointers likely point to functions in the DSO that has
already been unloaded...
A fix for that could be to call reinit_frame_cache in
jit_reader_unload_command _before_ unloading the jit reader DSO so
that the jit reader is given a chance to clean up the gdb_reg_values
before it is unloaded. However, the fix for the point below makes
this unnecessary, because it stops jit.c from keeping around
gdb_reg_values in the first place.
- However, it still makes sense to clear the frame cache when loading
or unloading a JIT unwinder.
This makes testing a JIT unwinder a bit simpler.
- Not only the frame cache actually -- gdb is not unloading the
jit-registered objfiles when the JIT reader is unloaded, and not
loading the already-registered descriptors when a JIT reader is
loaded.
The new test exercises unloading the jit reader, loading it back
again, and then making sure the JIT reader's unwinder works again.
Without the unload/re-load of already-read descriptors, the newly
loaded JIT would have no idea where the new function is, because
it's stored at symbol read time.
- I added a couple "info frame" calls to the test, and that
crashes GDB...
The problem is that jit_frame_prev_register assumes it'll only be
called for raw registers, so when it gets a pseudo register number,
the "priv->registers[reg]" access is really an out-of-bounds access.
To fix that, I made jit_frame_prev_register use
gdbarch_pseudo_register_read_value for reading the pseudo-registers.
However, that works with a regcache and we don't have one. To fix
that, I made the JIT unwinder store a regcache in its cache instead
of an array of gdb_reg_value pointers.
gdb/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* jit.c (jit_reader_load_command): Call reinit_frame_cache and
jit_inferior_created_hook.
(jit_reader_unload_command): Call reinit_frame_cache and
jit_inferior_exit_hook.
* jit.c (struct jit_unwind_private) <registers>: Delete field.
<regcache>: New field.
(jit_unwind_reg_set_impl): Set the register's value in the
regcache. Free the passed-in gdb_reg_value.
(jit_dealloc_cache): Adjust to free the regcache.
(jit_frame_sniffer): Allocate a regcache instead of an array of
gdb_reg_value pointers.
(jit_frame_this_id): Adjust.
(jit_frame_prev_register): Read raw registers off of the regcache
instead of from the gdb_reg_value pointer array. Use
gdbarch_pseudo_register_read_value to read pseudo registers.
* regcache.c (regcache_raw_set_cached_value): New function,
factored out from ...
(regcache_raw_write): ... here.
* regcache.h (regcache_raw_set_cached_value): Declare.
gdb/testsuite/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
* gdb.base/jit-reader.exp (info_registers_current_frame): New
procedure.
(jit_reader_test): Test the jit reader's unwinder.
* gdb.base/jithost.c (jit_function_00_code): New global.
(main): Use memcpy to fill in the mmapped code, instead of poking
bytes manually here.
* gdb.base/jitreader.c (enum register_mapping) <AMD64_RBP>: New
value.
(read_debug_info): Save the function's range.
(read_sp): New function.
(unwind_frame): Use it. Also unwind RBP.
(get_frame_id): Use read_sp.
(gdb_init_reader): Use calloc instead of malloc.
* lib/gdb.exp (get_hexadecimal_valueof): Add optional 'test'
parameter. Use gdb_test_multiple.
2016-07-01 12:56:39 +02:00
|
|
|
|
2016-06-17 20:24:08 +02:00
|
|
|
write_register (cbs, AMD64_RA, prev_ip);
|
|
|
|
write_register (cbs, AMD64_RSP, prev_sp);
|
Extend JIT-reader test and fix GDB problems that exposes
The jit-reader.exp test isn't really exercising the jit-reader's
unwinder API at all. This commit address that, and then fixes GDB
problems exposed.
- The custom JIT reader provided for the jit-reader.exp testcase
always rejects the jitted function's frame...
This is because the custom JIT reader in the testcase never ever
sets state->code_begin/end, so the bounds check in
gdb.base/jitreader.c:unwind_frame:
if (this_ip >= state->code_end || this_ip < state->code_begin)
return GDB_FAIL;
tends to fail, unless you're "lucky" (because it references
uninitialized data).
The result is that GDB is always actually using a built-in unwinder
for the jitted function.
- The provided unwinder doesn't do anything that GDB's built-in
unwinder can't do.
IOW, we can't really tell whether the JIT reader's unwinder is
working or not.
I fixed that by making the jitted function mangle its own stack
pointer with a xor, and then teaching the jit unwinder to demangle
it back (another xor). So now "backtrace" with GDB's built-in
unwinder fails while with the jit unwinder, it succeeds.
- GDB crashes after unloading the JIT reader, and flushing frames...
I made the testcase use the "flushregs" command after unloading the
JIT reader, to force the JIT frames to be flushed. However, that
crashes GDB...
When reinit_frame_cache tears down a frame's cache, it calls its
unwinder's dealloc_cache method, which for JIT frames ends up in
jit.c:jit_dealloc_cache. This function calls each of the frame's
gdb_reg_value's "free" pointer:
for (i = 0; i < gdbarch_num_regs (frame_arch); i++)
if (priv_data->registers[i] && priv_data->registers[i]->free)
priv_data->registers[i]->free (priv_data->registers[i]);
and the problem is these gdb_reg_value instances have been returned
by the JIT reader that has been already unloaded, and their "free"
function pointers likely point to functions in the DSO that has
already been unloaded...
A fix for that could be to call reinit_frame_cache in
jit_reader_unload_command _before_ unloading the jit reader DSO so
that the jit reader is given a chance to clean up the gdb_reg_values
before it is unloaded. However, the fix for the point below makes
this unnecessary, because it stops jit.c from keeping around
gdb_reg_values in the first place.
- However, it still makes sense to clear the frame cache when loading
or unloading a JIT unwinder.
This makes testing a JIT unwinder a bit simpler.
- Not only the frame cache actually -- gdb is not unloading the
jit-registered objfiles when the JIT reader is unloaded, and not
loading the already-registered descriptors when a JIT reader is
loaded.
The new test exercises unloading the jit reader, loading it back
again, and then making sure the JIT reader's unwinder works again.
Without the unload/re-load of already-read descriptors, the newly
loaded JIT would have no idea where the new function is, because
it's stored at symbol read time.
- I added a couple "info frame" calls to the test, and that
crashes GDB...
The problem is that jit_frame_prev_register assumes it'll only be
called for raw registers, so when it gets a pseudo register number,
the "priv->registers[reg]" access is really an out-of-bounds access.
To fix that, I made jit_frame_prev_register use
gdbarch_pseudo_register_read_value for reading the pseudo-registers.
However, that works with a regcache and we don't have one. To fix
that, I made the JIT unwinder store a regcache in its cache instead
of an array of gdb_reg_value pointers.
gdb/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* jit.c (jit_reader_load_command): Call reinit_frame_cache and
jit_inferior_created_hook.
(jit_reader_unload_command): Call reinit_frame_cache and
jit_inferior_exit_hook.
* jit.c (struct jit_unwind_private) <registers>: Delete field.
<regcache>: New field.
(jit_unwind_reg_set_impl): Set the register's value in the
regcache. Free the passed-in gdb_reg_value.
(jit_dealloc_cache): Adjust to free the regcache.
(jit_frame_sniffer): Allocate a regcache instead of an array of
gdb_reg_value pointers.
(jit_frame_this_id): Adjust.
(jit_frame_prev_register): Read raw registers off of the regcache
instead of from the gdb_reg_value pointer array. Use
gdbarch_pseudo_register_read_value to read pseudo registers.
* regcache.c (regcache_raw_set_cached_value): New function,
factored out from ...
(regcache_raw_write): ... here.
* regcache.h (regcache_raw_set_cached_value): Declare.
gdb/testsuite/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
* gdb.base/jit-reader.exp (info_registers_current_frame): New
procedure.
(jit_reader_test): Test the jit reader's unwinder.
* gdb.base/jithost.c (jit_function_00_code): New global.
(main): Use memcpy to fill in the mmapped code, instead of poking
bytes manually here.
* gdb.base/jitreader.c (enum register_mapping) <AMD64_RBP>: New
value.
(read_debug_info): Save the function's range.
(read_sp): New function.
(unwind_frame): Use it. Also unwind RBP.
(get_frame_id): Use read_sp.
(gdb_init_reader): Use calloc instead of malloc.
* lib/gdb.exp (get_hexadecimal_valueof): Add optional 'test'
parameter. Use gdb_test_multiple.
2016-07-01 12:56:39 +02:00
|
|
|
write_register (cbs, AMD64_RBP, prev_bp);
|
2016-06-17 20:24:08 +02:00
|
|
|
return GDB_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct gdb_frame_id
|
|
|
|
get_frame_id (struct gdb_reader_funcs *self, struct gdb_unwind_callbacks *cbs)
|
|
|
|
{
|
|
|
|
struct reader_state *state = (struct reader_state *) self->priv_data;
|
|
|
|
struct gdb_frame_id frame_id;
|
Extend JIT-reader test and fix GDB problems that exposes
The jit-reader.exp test isn't really exercising the jit-reader's
unwinder API at all. This commit address that, and then fixes GDB
problems exposed.
- The custom JIT reader provided for the jit-reader.exp testcase
always rejects the jitted function's frame...
This is because the custom JIT reader in the testcase never ever
sets state->code_begin/end, so the bounds check in
gdb.base/jitreader.c:unwind_frame:
if (this_ip >= state->code_end || this_ip < state->code_begin)
return GDB_FAIL;
tends to fail, unless you're "lucky" (because it references
uninitialized data).
The result is that GDB is always actually using a built-in unwinder
for the jitted function.
- The provided unwinder doesn't do anything that GDB's built-in
unwinder can't do.
IOW, we can't really tell whether the JIT reader's unwinder is
working or not.
I fixed that by making the jitted function mangle its own stack
pointer with a xor, and then teaching the jit unwinder to demangle
it back (another xor). So now "backtrace" with GDB's built-in
unwinder fails while with the jit unwinder, it succeeds.
- GDB crashes after unloading the JIT reader, and flushing frames...
I made the testcase use the "flushregs" command after unloading the
JIT reader, to force the JIT frames to be flushed. However, that
crashes GDB...
When reinit_frame_cache tears down a frame's cache, it calls its
unwinder's dealloc_cache method, which for JIT frames ends up in
jit.c:jit_dealloc_cache. This function calls each of the frame's
gdb_reg_value's "free" pointer:
for (i = 0; i < gdbarch_num_regs (frame_arch); i++)
if (priv_data->registers[i] && priv_data->registers[i]->free)
priv_data->registers[i]->free (priv_data->registers[i]);
and the problem is these gdb_reg_value instances have been returned
by the JIT reader that has been already unloaded, and their "free"
function pointers likely point to functions in the DSO that has
already been unloaded...
A fix for that could be to call reinit_frame_cache in
jit_reader_unload_command _before_ unloading the jit reader DSO so
that the jit reader is given a chance to clean up the gdb_reg_values
before it is unloaded. However, the fix for the point below makes
this unnecessary, because it stops jit.c from keeping around
gdb_reg_values in the first place.
- However, it still makes sense to clear the frame cache when loading
or unloading a JIT unwinder.
This makes testing a JIT unwinder a bit simpler.
- Not only the frame cache actually -- gdb is not unloading the
jit-registered objfiles when the JIT reader is unloaded, and not
loading the already-registered descriptors when a JIT reader is
loaded.
The new test exercises unloading the jit reader, loading it back
again, and then making sure the JIT reader's unwinder works again.
Without the unload/re-load of already-read descriptors, the newly
loaded JIT would have no idea where the new function is, because
it's stored at symbol read time.
- I added a couple "info frame" calls to the test, and that
crashes GDB...
The problem is that jit_frame_prev_register assumes it'll only be
called for raw registers, so when it gets a pseudo register number,
the "priv->registers[reg]" access is really an out-of-bounds access.
To fix that, I made jit_frame_prev_register use
gdbarch_pseudo_register_read_value for reading the pseudo-registers.
However, that works with a regcache and we don't have one. To fix
that, I made the JIT unwinder store a regcache in its cache instead
of an array of gdb_reg_value pointers.
gdb/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* jit.c (jit_reader_load_command): Call reinit_frame_cache and
jit_inferior_created_hook.
(jit_reader_unload_command): Call reinit_frame_cache and
jit_inferior_exit_hook.
* jit.c (struct jit_unwind_private) <registers>: Delete field.
<regcache>: New field.
(jit_unwind_reg_set_impl): Set the register's value in the
regcache. Free the passed-in gdb_reg_value.
(jit_dealloc_cache): Adjust to free the regcache.
(jit_frame_sniffer): Allocate a regcache instead of an array of
gdb_reg_value pointers.
(jit_frame_this_id): Adjust.
(jit_frame_prev_register): Read raw registers off of the regcache
instead of from the gdb_reg_value pointer array. Use
gdbarch_pseudo_register_read_value to read pseudo registers.
* regcache.c (regcache_raw_set_cached_value): New function,
factored out from ...
(regcache_raw_write): ... here.
* regcache.h (regcache_raw_set_cached_value): Declare.
gdb/testsuite/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
* gdb.base/jit-reader.exp (info_registers_current_frame): New
procedure.
(jit_reader_test): Test the jit reader's unwinder.
* gdb.base/jithost.c (jit_function_00_code): New global.
(main): Use memcpy to fill in the mmapped code, instead of poking
bytes manually here.
* gdb.base/jitreader.c (enum register_mapping) <AMD64_RBP>: New
value.
(read_debug_info): Save the function's range.
(read_sp): New function.
(unwind_frame): Use it. Also unwind RBP.
(get_frame_id): Use read_sp.
(gdb_init_reader): Use calloc instead of malloc.
* lib/gdb.exp (get_hexadecimal_valueof): Add optional 'test'
parameter. Use gdb_test_multiple.
2016-07-01 12:56:39 +02:00
|
|
|
uintptr_t ip;
|
2016-06-17 20:24:08 +02:00
|
|
|
uintptr_t sp;
|
Extend JIT-reader test and fix GDB problems that exposes
The jit-reader.exp test isn't really exercising the jit-reader's
unwinder API at all. This commit address that, and then fixes GDB
problems exposed.
- The custom JIT reader provided for the jit-reader.exp testcase
always rejects the jitted function's frame...
This is because the custom JIT reader in the testcase never ever
sets state->code_begin/end, so the bounds check in
gdb.base/jitreader.c:unwind_frame:
if (this_ip >= state->code_end || this_ip < state->code_begin)
return GDB_FAIL;
tends to fail, unless you're "lucky" (because it references
uninitialized data).
The result is that GDB is always actually using a built-in unwinder
for the jitted function.
- The provided unwinder doesn't do anything that GDB's built-in
unwinder can't do.
IOW, we can't really tell whether the JIT reader's unwinder is
working or not.
I fixed that by making the jitted function mangle its own stack
pointer with a xor, and then teaching the jit unwinder to demangle
it back (another xor). So now "backtrace" with GDB's built-in
unwinder fails while with the jit unwinder, it succeeds.
- GDB crashes after unloading the JIT reader, and flushing frames...
I made the testcase use the "flushregs" command after unloading the
JIT reader, to force the JIT frames to be flushed. However, that
crashes GDB...
When reinit_frame_cache tears down a frame's cache, it calls its
unwinder's dealloc_cache method, which for JIT frames ends up in
jit.c:jit_dealloc_cache. This function calls each of the frame's
gdb_reg_value's "free" pointer:
for (i = 0; i < gdbarch_num_regs (frame_arch); i++)
if (priv_data->registers[i] && priv_data->registers[i]->free)
priv_data->registers[i]->free (priv_data->registers[i]);
and the problem is these gdb_reg_value instances have been returned
by the JIT reader that has been already unloaded, and their "free"
function pointers likely point to functions in the DSO that has
already been unloaded...
A fix for that could be to call reinit_frame_cache in
jit_reader_unload_command _before_ unloading the jit reader DSO so
that the jit reader is given a chance to clean up the gdb_reg_values
before it is unloaded. However, the fix for the point below makes
this unnecessary, because it stops jit.c from keeping around
gdb_reg_values in the first place.
- However, it still makes sense to clear the frame cache when loading
or unloading a JIT unwinder.
This makes testing a JIT unwinder a bit simpler.
- Not only the frame cache actually -- gdb is not unloading the
jit-registered objfiles when the JIT reader is unloaded, and not
loading the already-registered descriptors when a JIT reader is
loaded.
The new test exercises unloading the jit reader, loading it back
again, and then making sure the JIT reader's unwinder works again.
Without the unload/re-load of already-read descriptors, the newly
loaded JIT would have no idea where the new function is, because
it's stored at symbol read time.
- I added a couple "info frame" calls to the test, and that
crashes GDB...
The problem is that jit_frame_prev_register assumes it'll only be
called for raw registers, so when it gets a pseudo register number,
the "priv->registers[reg]" access is really an out-of-bounds access.
To fix that, I made jit_frame_prev_register use
gdbarch_pseudo_register_read_value for reading the pseudo-registers.
However, that works with a regcache and we don't have one. To fix
that, I made the JIT unwinder store a regcache in its cache instead
of an array of gdb_reg_value pointers.
gdb/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* jit.c (jit_reader_load_command): Call reinit_frame_cache and
jit_inferior_created_hook.
(jit_reader_unload_command): Call reinit_frame_cache and
jit_inferior_exit_hook.
* jit.c (struct jit_unwind_private) <registers>: Delete field.
<regcache>: New field.
(jit_unwind_reg_set_impl): Set the register's value in the
regcache. Free the passed-in gdb_reg_value.
(jit_dealloc_cache): Adjust to free the regcache.
(jit_frame_sniffer): Allocate a regcache instead of an array of
gdb_reg_value pointers.
(jit_frame_this_id): Adjust.
(jit_frame_prev_register): Read raw registers off of the regcache
instead of from the gdb_reg_value pointer array. Use
gdbarch_pseudo_register_read_value to read pseudo registers.
* regcache.c (regcache_raw_set_cached_value): New function,
factored out from ...
(regcache_raw_write): ... here.
* regcache.h (regcache_raw_set_cached_value): Declare.
gdb/testsuite/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
* gdb.base/jit-reader.exp (info_registers_current_frame): New
procedure.
(jit_reader_test): Test the jit reader's unwinder.
* gdb.base/jithost.c (jit_function_00_code): New global.
(main): Use memcpy to fill in the mmapped code, instead of poking
bytes manually here.
* gdb.base/jitreader.c (enum register_mapping) <AMD64_RBP>: New
value.
(read_debug_info): Save the function's range.
(read_sp): New function.
(unwind_frame): Use it. Also unwind RBP.
(get_frame_id): Use read_sp.
(gdb_init_reader): Use calloc instead of malloc.
* lib/gdb.exp (get_hexadecimal_valueof): Add optional 'test'
parameter. Use gdb_test_multiple.
2016-07-01 12:56:39 +02:00
|
|
|
|
|
|
|
read_register (cbs, AMD64_RA, &ip);
|
|
|
|
read_sp (self, cbs, ip, &sp);
|
2016-06-17 20:24:08 +02:00
|
|
|
|
|
|
|
frame_id.code_address = (GDB_CORE_ADDR) state->code_begin;
|
|
|
|
frame_id.stack_address = (GDB_CORE_ADDR) sp;
|
|
|
|
|
|
|
|
return frame_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
destroy_reader (struct gdb_reader_funcs *self)
|
|
|
|
{
|
|
|
|
free (self->priv_data);
|
|
|
|
free (self);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct gdb_reader_funcs *
|
|
|
|
gdb_init_reader (void)
|
|
|
|
{
|
Extend JIT-reader test and fix GDB problems that exposes
The jit-reader.exp test isn't really exercising the jit-reader's
unwinder API at all. This commit address that, and then fixes GDB
problems exposed.
- The custom JIT reader provided for the jit-reader.exp testcase
always rejects the jitted function's frame...
This is because the custom JIT reader in the testcase never ever
sets state->code_begin/end, so the bounds check in
gdb.base/jitreader.c:unwind_frame:
if (this_ip >= state->code_end || this_ip < state->code_begin)
return GDB_FAIL;
tends to fail, unless you're "lucky" (because it references
uninitialized data).
The result is that GDB is always actually using a built-in unwinder
for the jitted function.
- The provided unwinder doesn't do anything that GDB's built-in
unwinder can't do.
IOW, we can't really tell whether the JIT reader's unwinder is
working or not.
I fixed that by making the jitted function mangle its own stack
pointer with a xor, and then teaching the jit unwinder to demangle
it back (another xor). So now "backtrace" with GDB's built-in
unwinder fails while with the jit unwinder, it succeeds.
- GDB crashes after unloading the JIT reader, and flushing frames...
I made the testcase use the "flushregs" command after unloading the
JIT reader, to force the JIT frames to be flushed. However, that
crashes GDB...
When reinit_frame_cache tears down a frame's cache, it calls its
unwinder's dealloc_cache method, which for JIT frames ends up in
jit.c:jit_dealloc_cache. This function calls each of the frame's
gdb_reg_value's "free" pointer:
for (i = 0; i < gdbarch_num_regs (frame_arch); i++)
if (priv_data->registers[i] && priv_data->registers[i]->free)
priv_data->registers[i]->free (priv_data->registers[i]);
and the problem is these gdb_reg_value instances have been returned
by the JIT reader that has been already unloaded, and their "free"
function pointers likely point to functions in the DSO that has
already been unloaded...
A fix for that could be to call reinit_frame_cache in
jit_reader_unload_command _before_ unloading the jit reader DSO so
that the jit reader is given a chance to clean up the gdb_reg_values
before it is unloaded. However, the fix for the point below makes
this unnecessary, because it stops jit.c from keeping around
gdb_reg_values in the first place.
- However, it still makes sense to clear the frame cache when loading
or unloading a JIT unwinder.
This makes testing a JIT unwinder a bit simpler.
- Not only the frame cache actually -- gdb is not unloading the
jit-registered objfiles when the JIT reader is unloaded, and not
loading the already-registered descriptors when a JIT reader is
loaded.
The new test exercises unloading the jit reader, loading it back
again, and then making sure the JIT reader's unwinder works again.
Without the unload/re-load of already-read descriptors, the newly
loaded JIT would have no idea where the new function is, because
it's stored at symbol read time.
- I added a couple "info frame" calls to the test, and that
crashes GDB...
The problem is that jit_frame_prev_register assumes it'll only be
called for raw registers, so when it gets a pseudo register number,
the "priv->registers[reg]" access is really an out-of-bounds access.
To fix that, I made jit_frame_prev_register use
gdbarch_pseudo_register_read_value for reading the pseudo-registers.
However, that works with a regcache and we don't have one. To fix
that, I made the JIT unwinder store a regcache in its cache instead
of an array of gdb_reg_value pointers.
gdb/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Tom Tromey <tom@tromey.com>
* jit.c (jit_reader_load_command): Call reinit_frame_cache and
jit_inferior_created_hook.
(jit_reader_unload_command): Call reinit_frame_cache and
jit_inferior_exit_hook.
* jit.c (struct jit_unwind_private) <registers>: Delete field.
<regcache>: New field.
(jit_unwind_reg_set_impl): Set the register's value in the
regcache. Free the passed-in gdb_reg_value.
(jit_dealloc_cache): Adjust to free the regcache.
(jit_frame_sniffer): Allocate a regcache instead of an array of
gdb_reg_value pointers.
(jit_frame_this_id): Adjust.
(jit_frame_prev_register): Read raw registers off of the regcache
instead of from the gdb_reg_value pointer array. Use
gdbarch_pseudo_register_read_value to read pseudo registers.
* regcache.c (regcache_raw_set_cached_value): New function,
factored out from ...
(regcache_raw_write): ... here.
* regcache.h (regcache_raw_set_cached_value): Declare.
gdb/testsuite/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
* gdb.base/jit-reader.exp (info_registers_current_frame): New
procedure.
(jit_reader_test): Test the jit reader's unwinder.
* gdb.base/jithost.c (jit_function_00_code): New global.
(main): Use memcpy to fill in the mmapped code, instead of poking
bytes manually here.
* gdb.base/jitreader.c (enum register_mapping) <AMD64_RBP>: New
value.
(read_debug_info): Save the function's range.
(read_sp): New function.
(unwind_frame): Use it. Also unwind RBP.
(get_frame_id): Use read_sp.
(gdb_init_reader): Use calloc instead of malloc.
* lib/gdb.exp (get_hexadecimal_valueof): Add optional 'test'
parameter. Use gdb_test_multiple.
2016-07-01 12:56:39 +02:00
|
|
|
struct reader_state *state = calloc (1, sizeof (struct reader_state));
|
2016-06-17 20:24:08 +02:00
|
|
|
struct gdb_reader_funcs *reader_funcs =
|
|
|
|
malloc (sizeof (struct gdb_reader_funcs));
|
|
|
|
|
|
|
|
reader_funcs->reader_version = GDB_READER_INTERFACE_VERSION;
|
|
|
|
reader_funcs->priv_data = state;
|
|
|
|
reader_funcs->read = read_debug_info;
|
|
|
|
reader_funcs->unwind = unwind_frame;
|
|
|
|
reader_funcs->get_frame_id = get_frame_id;
|
|
|
|
reader_funcs->destroy = destroy_reader;
|
|
|
|
|
|
|
|
return reader_funcs;
|
|
|
|
}
|