* PATCH: PR gdb/13969: GDBserver doesn't check unsupported binary
@ 2012-04-11 20:36 H.J. Lu
2012-04-12 13:52 ` Pedro Alves
0 siblings, 1 reply; 9+ messages in thread
From: H.J. Lu @ 2012-04-11 20:36 UTC (permalink / raw)
To: GDB
Hi,
This patch checks if a binary is supported by GDBserver. Also checking
ELF64 isn't very reliable to detect 64bit register support since x32
is ELF32, but it does support 64bit register. This patch checks the
e_machine field for 64bit register support. OK for trunk?
Thanks.
H.J.
---
2012-04-11 H.J. Lu <hongjiu.lu@intel.com>
PR gdb/13969
* linux-low.c (linux_pid_exe_is_elf_64_file): Also return the
e_machine field.
(linux_qxfer_libraries_svr4): Update call to elf_64_file_p.
* linux-low.h (linux_pid_exe_is_elf_64_file): Updated.
* linux-x86-low.c (linux_is_64bit): New.
(x86_arch_setup): Check if GDBserver is compatible with
process.
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index f7a83f4..35d7e69 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -263,13 +263,19 @@ static void wait_for_sigstop (struct inferior_list_entry *entry);
/* Return non-zero if HEADER is a 64-bit ELF file. */
static int
-elf_64_header_p (const Elf64_Ehdr *header)
+elf_64_header_p (const Elf64_Ehdr *header, unsigned int *machine)
{
- return (header->e_ident[EI_MAG0] == ELFMAG0
- && header->e_ident[EI_MAG1] == ELFMAG1
- && header->e_ident[EI_MAG2] == ELFMAG2
- && header->e_ident[EI_MAG3] == ELFMAG3
- && header->e_ident[EI_CLASS] == ELFCLASS64);
+ if (header->e_ident[EI_MAG0] == ELFMAG0
+ && header->e_ident[EI_MAG1] == ELFMAG1
+ && header->e_ident[EI_MAG2] == ELFMAG2
+ && header->e_ident[EI_MAG3] == ELFMAG3)
+ {
+ *machine = header->e_machine;
+ return header->e_ident[EI_CLASS] == ELFCLASS64;
+
+ }
+ *machine = EM_NONE;
+ return -1;
}
/* Return non-zero if FILE is a 64-bit ELF file,
@@ -277,7 +283,7 @@ elf_64_header_p (const Elf64_Ehdr *header)
and -1 if the file is not accessible or doesn't exist. */
static int
-elf_64_file_p (const char *file)
+elf_64_file_p (const char *file, unsigned int *machine)
{
Elf64_Ehdr header;
int fd;
@@ -293,19 +299,19 @@ elf_64_file_p (const char *file)
}
close (fd);
- return elf_64_header_p (&header);
+ return elf_64_header_p (&header, machine);
}
/* Accepts an integer PID; Returns true if the executable PID is
running is a 64-bit ELF file.. */
int
-linux_pid_exe_is_elf_64_file (int pid)
+linux_pid_exe_is_elf_64_file (int pid, unsigned int *machine)
{
char file[MAXPATHLEN];
sprintf (file, "/proc/%d/exe", pid);
- return elf_64_file_p (file);
+ return elf_64_file_p (file, machine);
}
static void
@@ -5584,6 +5590,7 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
32 /* l_prev offset in link_map. */
};
const struct link_map_offsets *lmo;
+ unsigned int machine;
if (writebuf != NULL)
return -2;
@@ -5592,7 +5599,7 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
pid = lwpid_of (get_thread_lwp (current_inferior));
xsnprintf (filename, sizeof filename, "/proc/%d/exe", pid);
- is_elf64 = elf_64_file_p (filename);
+ is_elf64 = elf_64_file_p (filename, &machine);
lmo = is_elf64 ? &lmo_64bit_offsets : &lmo_32bit_offsets;
if (priv->r_debug == 0)
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index 07eda12..a1a6777 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -278,7 +278,7 @@ struct lwp_info
extern struct inferior_list all_lwps;
-int linux_pid_exe_is_elf_64_file (int pid);
+int linux_pid_exe_is_elf_64_file (int pid, unsigned int *machine);
void linux_attach_lwp (unsigned long pid);
struct lwp_info *find_lwp_pid (ptid_t ptid);
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 7feb721..8a4ab50 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -1106,17 +1106,28 @@ x86_linux_process_qsupported (const char *query)
static void
x86_arch_setup (void)
{
-#ifdef __x86_64__
int pid = pid_of (get_thread_lwp (current_inferior));
- int use_64bit = linux_pid_exe_is_elf_64_file (pid);
+ unsigned int machine;
+ int use_64bit = linux_pid_exe_is_elf_64_file (pid, &machine);
+ if (sizeof (void *) == 4)
+ {
+ if (use_64bit > 0)
+ error (_("Can't debug 64-bit process with 32-bit GDBserver"));
+#ifndef __x86_64__
+ else if (machine == EM_X86_64)
+ error (_("Can't debug x86-64 process with 32-bit GDBserver"));
+#endif
+ }
+
+#ifdef __x86_64__
if (use_64bit < 0)
{
/* This can only happen if /proc/<pid>/exe is unreadable,
but "that can't happen" if we've gotten this far.
Fall through and assume this is a 32-bit program. */
}
- else if (use_64bit)
+ else if (machine == EM_X86_64)
{
/* Amd64 doesn't have HAVE_LINUX_USRREGS. */
the_low_target.num_regs = -1;
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: PATCH: PR gdb/13969: GDBserver doesn't check unsupported binary
2012-04-11 20:36 PATCH: PR gdb/13969: GDBserver doesn't check unsupported binary H.J. Lu
@ 2012-04-12 13:52 ` Pedro Alves
2012-04-12 15:58 ` H.J. Lu
0 siblings, 1 reply; 9+ messages in thread
From: Pedro Alves @ 2012-04-12 13:52 UTC (permalink / raw)
To: H.J. Lu; +Cc: H.J. Lu, GDB
On 04/11/2012 08:16 PM, H.J. Lu wrote:
> 2012-04-11 H.J. Lu <hongjiu.lu@intel.com>
>
> PR gdb/13969
> * linux-low.c (linux_pid_exe_is_elf_64_file): Also return the
> e_machine field.
> (linux_qxfer_libraries_svr4): Update call to elf_64_file_p.
>
> * linux-low.h (linux_pid_exe_is_elf_64_file): Updated.
>
> * linux-x86-low.c (linux_is_64bit): New.
I don't see a new linux_is_64bit symbol in the patch.
> (x86_arch_setup): Check if GDBserver is compatible with
> process.
These all all logically related changes. Please drop the empty lines.
> --- a/gdb/gdbserver/linux-x86-low.c
> +++ b/gdb/gdbserver/linux-x86-low.c
> @@ -1106,17 +1106,28 @@ x86_linux_process_qsupported (const char *query)
> static void
> x86_arch_setup (void)
> {
> -#ifdef __x86_64__
> int pid = pid_of (get_thread_lwp (current_inferior));
> - int use_64bit = linux_pid_exe_is_elf_64_file (pid);
> + unsigned int machine;
> + int use_64bit = linux_pid_exe_is_elf_64_file (pid, &machine);
>
> + if (sizeof (void *) == 4)
> + {
> + if (use_64bit > 0)
> + error (_("Can't debug 64-bit process with 32-bit GDBserver"));
> +#ifndef __x86_64__
> + else if (machine == EM_X86_64)
> + error (_("Can't debug x86-64 process with 32-bit GDBserver"));
> +#endif
> + }
> +
> +#ifdef __x86_64__
> if (use_64bit < 0)
Please rename use_64bit to something like is_elf64. The code reads
now a bit confusingly with "use_64bit". Okay with that change,
and the ChangeLog entry fixed.
I assume there's no kernel limitation that would prevent a x32
gdbserver from debugging a 64-bit process?
--
Pedro Alves
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: PATCH: PR gdb/13969: GDBserver doesn't check unsupported binary
2012-04-12 13:52 ` Pedro Alves
@ 2012-04-12 15:58 ` H.J. Lu
2012-04-12 16:01 ` Pedro Alves
0 siblings, 1 reply; 9+ messages in thread
From: H.J. Lu @ 2012-04-12 15:58 UTC (permalink / raw)
To: Pedro Alves; +Cc: GDB
On Thu, Apr 12, 2012 at 6:09 AM, Pedro Alves <palves@redhat.com> wrote:
> On 04/11/2012 08:16 PM, H.J. Lu wrote:
>
>> 2012-04-11 H.J. Lu <hongjiu.lu@intel.com>
>>
>> PR gdb/13969
>> * linux-low.c (linux_pid_exe_is_elf_64_file): Also return the
>> e_machine field.
>> (linux_qxfer_libraries_svr4): Update call to elf_64_file_p.
>>
>> * linux-low.h (linux_pid_exe_is_elf_64_file): Updated.
>>
>> * linux-x86-low.c (linux_is_64bit): New.
>
>
> I don't see a new linux_is_64bit symbol in the patch.
Removed.
>> (x86_arch_setup): Check if GDBserver is compatible with
>> process.
>
>
> These all all logically related changes. Please drop the empty lines.
Done.
>
>> --- a/gdb/gdbserver/linux-x86-low.c
>
>> +++ b/gdb/gdbserver/linux-x86-low.c
>> @@ -1106,17 +1106,28 @@ x86_linux_process_qsupported (const char *query)
>> static void
>> x86_arch_setup (void)
>> {
>> -#ifdef __x86_64__
>> int pid = pid_of (get_thread_lwp (current_inferior));
>> - int use_64bit = linux_pid_exe_is_elf_64_file (pid);
>> + unsigned int machine;
>> + int use_64bit = linux_pid_exe_is_elf_64_file (pid, &machine);
>>
>> + if (sizeof (void *) == 4)
>> + {
>> + if (use_64bit > 0)
>> + error (_("Can't debug 64-bit process with 32-bit GDBserver"));
>> +#ifndef __x86_64__
>> + else if (machine == EM_X86_64)
>> + error (_("Can't debug x86-64 process with 32-bit GDBserver"));
>> +#endif
>> + }
>> +
>> +#ifdef __x86_64__
>> if (use_64bit < 0)
>
>
> Please rename use_64bit to something like is_elf64. The code reads
> now a bit confusingly with "use_64bit". Okay with that change,
> and the ChangeLog entry fixed.
Done. I checked in the updated patch.
> I assume there's no kernel limitation that would prevent a x32
> gdbserver from debugging a 64-bit process?
>
It doesn't work since x32 is a 32-bit process. Although x32
GDBserver can get registers of 64-bit process, it can't handle
64-bit address in 64b-bit process, like setting break points.
--
H.J.
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: PATCH: PR gdb/13969: GDBserver doesn't check unsupported binary
2012-04-12 15:58 ` H.J. Lu
@ 2012-04-12 16:01 ` Pedro Alves
2012-04-12 16:38 ` H.J. Lu
0 siblings, 1 reply; 9+ messages in thread
From: Pedro Alves @ 2012-04-12 16:01 UTC (permalink / raw)
To: H.J. Lu; +Cc: GDB
On 04/12/2012 04:37 PM, H.J. Lu wrote:
> It doesn't work since x32 is a 32-bit process. Although x32
> GDBserver can get registers of 64-bit process, it can't handle 64-bit address
> in 64b-bit process, like setting break points.
Oh yeah... PowerPC has PPC_PTRACE_PEEKDATA_3264/PPC_PTRACE_POKEDATA_3264
for that, but well, it's PowerPC specific.
--
Pedro Alves
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: PATCH: PR gdb/13969: GDBserver doesn't check unsupported binary
2012-04-12 16:01 ` Pedro Alves
@ 2012-04-12 16:38 ` H.J. Lu
2012-04-12 16:45 ` Pedro Alves
0 siblings, 1 reply; 9+ messages in thread
From: H.J. Lu @ 2012-04-12 16:38 UTC (permalink / raw)
To: Pedro Alves; +Cc: GDB
On Thu, Apr 12, 2012 at 8:57 AM, Pedro Alves <palves@redhat.com> wrote:
> On 04/12/2012 04:37 PM, H.J. Lu wrote:
>
>> It doesn't work since x32 is a 32-bit process. Although x32
>> GDBserver can get registers of 64-bit process, it can't handle 64-bit address
>
>> in 64b-bit process, like setting break points.
>
> Oh yeah... PowerPC has PPC_PTRACE_PEEKDATA_3264/PPC_PTRACE_POKEDATA_3264
> for that, but well, it's PowerPC specific.
>
Also x32 siginfo is different from 64bit signfo. X32 ptrace can't get 64bit
siginfo due to address fields in siginfo.
--
H.J.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: PATCH: PR gdb/13969: GDBserver doesn't check unsupported binary
2012-04-12 16:38 ` H.J. Lu
@ 2012-04-12 16:45 ` Pedro Alves
2012-04-12 16:53 ` H.J. Lu
0 siblings, 1 reply; 9+ messages in thread
From: Pedro Alves @ 2012-04-12 16:45 UTC (permalink / raw)
To: H.J. Lu; +Cc: GDB
On 04/12/2012 05:25 PM, H.J. Lu wrote:
> On Thu, Apr 12, 2012 at 8:57 AM, Pedro Alves <palves@redhat.com> wrote:
>> On 04/12/2012 04:37 PM, H.J. Lu wrote:
>>
>>> It doesn't work since x32 is a 32-bit process. Although x32
>>> GDBserver can get registers of 64-bit process, it can't handle 64-bit address
>>
>>> in 64b-bit process, like setting break points.
>>
>> Oh yeah... PowerPC has PPC_PTRACE_PEEKDATA_3264/PPC_PTRACE_POKEDATA_3264
>> for that, but well, it's PowerPC specific.
>>
>
> Also x32 siginfo is different from 64bit signfo. X32 ptrace can't get 64bit
> siginfo due to address fields in siginfo.
Are you certain about that? With a 64-bit debugger vs 32-bit process,
PTRACE_GETSIGINFO returns the siginfo in 64-bit layout. I could see the
kernel returning 64-bit siginfo for x32 too (it's a question of whether
the kernel returns its native layout, or the debugger's).
In the 64x32 case, GDB has to go through contortions to
translate the siginfo layout (in both directions), for the
$_siginfo convenience variable's support. This ends up needing to
replicate what the kernel's compat layer does. IMO, a PTRACE_
method that always returned the siginfo object in the layout of the
inferior would be nice.
--
Pedro Alves
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: PATCH: PR gdb/13969: GDBserver doesn't check unsupported binary
2012-04-12 16:45 ` Pedro Alves
@ 2012-04-12 16:53 ` H.J. Lu
2012-04-12 17:20 ` Pedro Alves
0 siblings, 1 reply; 9+ messages in thread
From: H.J. Lu @ 2012-04-12 16:53 UTC (permalink / raw)
To: Pedro Alves; +Cc: GDB
On Thu, Apr 12, 2012 at 9:38 AM, Pedro Alves <palves@redhat.com> wrote:
> On 04/12/2012 05:25 PM, H.J. Lu wrote:
>
>> On Thu, Apr 12, 2012 at 8:57 AM, Pedro Alves <palves@redhat.com> wrote:
>>> On 04/12/2012 04:37 PM, H.J. Lu wrote:
>>>
>>>> It doesn't work since x32 is a 32-bit process. Although x32
>>>> GDBserver can get registers of 64-bit process, it can't handle 64-bit address
>>>
>>>> in 64b-bit process, like setting break points.
>>>
>>> Oh yeah... PowerPC has PPC_PTRACE_PEEKDATA_3264/PPC_PTRACE_POKEDATA_3264
>>> for that, but well, it's PowerPC specific.
>>>
>>
>> Also x32 siginfo is different from 64bit signfo. X32 ptrace can't get 64bit
>> siginfo due to address fields in siginfo.
>
>
> Are you certain about that? With a 64-bit debugger vs 32-bit process,
> PTRACE_GETSIGINFO returns the siginfo in 64-bit layout. I could see the
> kernel returning 64-bit siginfo for x32 too (it's a question of whether
> the kernel returns its native layout, or the debugger's).
>
> In the 64x32 case, GDB has to go through contortions to
> translate the siginfo layout (in both directions), for the
> $_siginfo convenience variable's support. This ends up needing to
> replicate what the kernel's compat layer does. IMO, a PTRACE_
> method that always returned the siginfo object in the layout of the
> inferior would be nice.
>
x32 ptrace returns x32 siginfo, which is compatible with
ia32 inferior, but not 64bit inferior, due to
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
struct
{
void *si_addr; /* Faulting insn/memory ref. */
} _sigfault;
si_addr is 32bit for x32 ptrace.
--
H.J.
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: PATCH: PR gdb/13969: GDBserver doesn't check unsupported binary
2012-04-12 16:53 ` H.J. Lu
@ 2012-04-12 17:20 ` Pedro Alves
2012-04-12 18:05 ` H.J. Lu
0 siblings, 1 reply; 9+ messages in thread
From: Pedro Alves @ 2012-04-12 17:20 UTC (permalink / raw)
To: H.J. Lu; +Cc: GDB
On 04/12/2012 05:45 PM, H.J. Lu wrote:
> x32 ptrace returns x32 siginfo,
ok.
> which is compatible with ia32 inferior
I believe clock_t will be 64-bit with x32, however, right?
If so, amd64-linux-nat.c:compat_siginfo_from_siginfo|siginfo_from_compat_siginfo
(and the gdbserver equivalents) will need adjustment (for the 64-bit X x32 case).
This is something most probably not caught by the testsuite.
--
Pedro Alves
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-04-12 17:21 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-11 20:36 PATCH: PR gdb/13969: GDBserver doesn't check unsupported binary H.J. Lu
2012-04-12 13:52 ` Pedro Alves
2012-04-12 15:58 ` H.J. Lu
2012-04-12 16:01 ` Pedro Alves
2012-04-12 16:38 ` H.J. Lu
2012-04-12 16:45 ` Pedro Alves
2012-04-12 16:53 ` H.J. Lu
2012-04-12 17:20 ` Pedro Alves
2012-04-12 18:05 ` H.J. Lu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox