gdb/
* common/linux-ptrace.c: Include gdb_assert.h. <__i386__> (linux_ptrace_test_ret_to_nx_instr): New declaration. <__i386__>: Include sys/reg.h, sys/mman.h, signal.h, sys/wait.h and stdint.h. (linux_ptrace_test_ret_to_nx, linux_ptrace_init_warnings): New functions. * common/linux-ptrace.h (linux_ptrace_init_warnings): New declarations. * linux-nat.c (linux_child_post_attach) (linux_child_post_startup_inferior): Call linux_ptrace_init_warnings. gdb/gdbserver/ * gdbserver/linux-low.c (initialize_low): Call linux_ptrace_init_warnings.
This commit is contained in:
parent
889003ed52
commit
aa7c744796
|
@ -1,3 +1,15 @@
|
||||||
|
2012-07-07 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
|
* common/linux-ptrace.c: Include gdb_assert.h.
|
||||||
|
<__i386__> (linux_ptrace_test_ret_to_nx_instr): New declaration.
|
||||||
|
<__i386__>: Include sys/reg.h, sys/mman.h, signal.h, sys/wait.h and
|
||||||
|
stdint.h.
|
||||||
|
(linux_ptrace_test_ret_to_nx, linux_ptrace_init_warnings): New
|
||||||
|
functions.
|
||||||
|
* common/linux-ptrace.h (linux_ptrace_init_warnings): New declarations.
|
||||||
|
* linux-nat.c (linux_child_post_attach)
|
||||||
|
(linux_child_post_startup_inferior): Call linux_ptrace_init_warnings.
|
||||||
|
|
||||||
2012-07-07 Jan Kratochvil <jan.kratochvil@redhat.com>
|
2012-07-07 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
* linux-thread-db.c (thread_db_find_new_threads_silently): Do not apply
|
* linux-thread-db.c (thread_db_find_new_threads_silently): Do not apply
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "linux-ptrace.h"
|
#include "linux-ptrace.h"
|
||||||
#include "linux-procfs.h"
|
#include "linux-procfs.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
#include "gdb_assert.h"
|
||||||
|
|
||||||
/* Find all possible reasons we could fail to attach PID and append these
|
/* Find all possible reasons we could fail to attach PID and append these
|
||||||
newline terminated reason strings to initialized BUFFER. '\0' termination
|
newline terminated reason strings to initialized BUFFER. '\0' termination
|
||||||
|
@ -47,3 +48,126 @@ linux_ptrace_attach_warnings (pid_t pid, struct buffer *buffer)
|
||||||
"- the process has already terminated\n"),
|
"- the process has already terminated\n"),
|
||||||
(int) pid);
|
(int) pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __i386__
|
||||||
|
|
||||||
|
/* Address of the 'ret' instruction in asm code block below. */
|
||||||
|
extern void (linux_ptrace_test_ret_to_nx_instr) (void);
|
||||||
|
|
||||||
|
#include <sys/reg.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#endif /* __i386__ */
|
||||||
|
|
||||||
|
/* Test broken off-trunk Linux kernel patchset for NX support on i386. It was
|
||||||
|
removed in Fedora kernel 88fa1f0332d188795ed73d7ac2b1564e11a0b4cd. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
linux_ptrace_test_ret_to_nx (void)
|
||||||
|
{
|
||||||
|
#ifdef __i386__
|
||||||
|
pid_t child, got_pid;
|
||||||
|
gdb_byte *return_address, *pc;
|
||||||
|
long l;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
return_address = mmap (NULL, 2, PROT_READ | PROT_WRITE,
|
||||||
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
|
if (return_address == MAP_FAILED)
|
||||||
|
{
|
||||||
|
warning (_("linux_ptrace_test_ret_to_nx: Cannot mmap: %s"),
|
||||||
|
strerror (errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put there 'int3'. */
|
||||||
|
*return_address = 0xcc;
|
||||||
|
|
||||||
|
child = fork ();
|
||||||
|
switch (child)
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
warning (_("linux_ptrace_test_ret_to_nx: Cannot fork: %s"),
|
||||||
|
strerror (errno));
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
l = ptrace (PTRACE_TRACEME, 0, NULL, NULL);
|
||||||
|
if (l != 0)
|
||||||
|
warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_TRACEME: %s"),
|
||||||
|
strerror (errno));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
asm volatile ("pushl %0;"
|
||||||
|
".globl linux_ptrace_test_ret_to_nx_instr;"
|
||||||
|
"linux_ptrace_test_ret_to_nx_instr:"
|
||||||
|
"ret"
|
||||||
|
: : "r" (return_address) : "%esp", "memory");
|
||||||
|
gdb_assert_not_reached ("asm block did not terminate");
|
||||||
|
}
|
||||||
|
|
||||||
|
_exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
got_pid = waitpid (child, &status, 0);
|
||||||
|
gdb_assert (got_pid == child);
|
||||||
|
gdb_assert (WIFSTOPPED (status));
|
||||||
|
|
||||||
|
/* We may get SIGSEGV due to missing PROT_EXEC of the return_address. */
|
||||||
|
gdb_assert (WSTOPSIG (status) == SIGTRAP || WSTOPSIG (status) == SIGSEGV);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
l = ptrace (PTRACE_PEEKUSER, child, (void *) (uintptr_t) (EIP * 4), NULL);
|
||||||
|
gdb_assert (errno == 0);
|
||||||
|
pc = (void *) (uintptr_t) l;
|
||||||
|
|
||||||
|
if (ptrace (PTRACE_KILL, child, NULL, NULL) != 0)
|
||||||
|
warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_KILL: %s"),
|
||||||
|
strerror (errno));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int kill_status;
|
||||||
|
|
||||||
|
got_pid = waitpid (child, &kill_status, 0);
|
||||||
|
gdb_assert (got_pid == child);
|
||||||
|
gdb_assert (WIFSIGNALED (kill_status));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* + 1 is there as x86* stops after the 'int3' instruction. */
|
||||||
|
if (WSTOPSIG (status) == SIGTRAP && pc == return_address + 1)
|
||||||
|
{
|
||||||
|
/* PASS */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We may get SIGSEGV due to missing PROT_EXEC of the RETURN_ADDRESS page. */
|
||||||
|
if (WSTOPSIG (status) == SIGSEGV && pc == return_address)
|
||||||
|
{
|
||||||
|
/* PASS */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_assert ((void (*) (void)) pc == &linux_ptrace_test_ret_to_nx_instr);
|
||||||
|
|
||||||
|
warning (_("Cannot call inferior functions, you have broken "
|
||||||
|
"Linux kernel i386 NX (non-executable pages) support!"));
|
||||||
|
#endif /* __i386__ */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Display possible problems on this system. Display them only once per GDB
|
||||||
|
execution. */
|
||||||
|
|
||||||
|
void
|
||||||
|
linux_ptrace_init_warnings (void)
|
||||||
|
{
|
||||||
|
static int warned = 0;
|
||||||
|
|
||||||
|
if (warned)
|
||||||
|
return;
|
||||||
|
warned = 1;
|
||||||
|
|
||||||
|
linux_ptrace_test_ret_to_nx ();
|
||||||
|
}
|
||||||
|
|
|
@ -68,5 +68,6 @@ struct buffer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void linux_ptrace_attach_warnings (pid_t pid, struct buffer *buffer);
|
extern void linux_ptrace_attach_warnings (pid_t pid, struct buffer *buffer);
|
||||||
|
extern void linux_ptrace_init_warnings (void);
|
||||||
|
|
||||||
#endif /* COMMON_LINUX_PTRACE_H */
|
#endif /* COMMON_LINUX_PTRACE_H */
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2012-07-07 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
|
* gdbserver/linux-low.c (initialize_low): Call
|
||||||
|
linux_ptrace_init_warnings.
|
||||||
|
|
||||||
2012-07-02 Doug Evans <dje@google.com>
|
2012-07-02 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
* mem-break.c (gdb_no_commands_at_breakpoint): Fix cast from
|
* mem-break.c (gdb_no_commands_at_breakpoint): Fix cast from
|
||||||
|
|
|
@ -5878,6 +5878,7 @@ initialize_low (void)
|
||||||
the_low_target.breakpoint_len);
|
the_low_target.breakpoint_len);
|
||||||
linux_init_signals ();
|
linux_init_signals ();
|
||||||
linux_test_for_tracefork ();
|
linux_test_for_tracefork ();
|
||||||
|
linux_ptrace_init_warnings ();
|
||||||
#ifdef HAVE_LINUX_REGSETS
|
#ifdef HAVE_LINUX_REGSETS
|
||||||
for (num_regsets = 0; target_regsets[num_regsets].size >= 0; num_regsets++)
|
for (num_regsets = 0; target_regsets[num_regsets].size >= 0; num_regsets++)
|
||||||
;
|
;
|
||||||
|
|
|
@ -583,6 +583,7 @@ linux_child_post_attach (int pid)
|
||||||
{
|
{
|
||||||
linux_enable_event_reporting (pid_to_ptid (pid));
|
linux_enable_event_reporting (pid_to_ptid (pid));
|
||||||
linux_enable_tracesysgood (pid_to_ptid (pid));
|
linux_enable_tracesysgood (pid_to_ptid (pid));
|
||||||
|
linux_ptrace_init_warnings ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -590,6 +591,7 @@ linux_child_post_startup_inferior (ptid_t ptid)
|
||||||
{
|
{
|
||||||
linux_enable_event_reporting (ptid);
|
linux_enable_event_reporting (ptid);
|
||||||
linux_enable_tracesysgood (ptid);
|
linux_enable_tracesysgood (ptid);
|
||||||
|
linux_ptrace_init_warnings ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the number of known LWPs in the tgid given by PID. */
|
/* Return the number of known LWPs in the tgid given by PID. */
|
||||||
|
|
Loading…
Reference in New Issue