Check if GDBserver is compatible with process
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 12 Apr 2012 15:35:32 +0000 (15:35 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 12 Apr 2012 15:35:32 +0000 (15:35 +0000)
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 (x86_arch_setup): Check if GDBserver is
compatible with process.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c
gdb/gdbserver/linux-low.h
gdb/gdbserver/linux-x86-low.c

index 721dc1d2bb25682ef4778b09425315d695f52f11..f1a61650c565e95de453a283e8d6abf754832a6e 100644 (file)
@@ -1,3 +1,13 @@
+2012-04-12  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 (x86_arch_setup): Check if GDBserver is
+       compatible with process.
+
 2012-04-12  Yao Qi  <yao@codesourcery.com>
 
        * Makefile.in: Define abs_top_srcdir and abs_srcdir.
index f7a83f4fc60a4fc13c6ce9754cb02a8f6576753b..35d7e69f865c049c236bcdd2c90ba6fd15973a82 100644 (file)
@@ -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)
index 07eda12de1686ec5199214008d495f57eb6b4aa5..a1a6777ddc8d88e357cf1e09474f53a9171199d4 100644 (file)
@@ -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);
index 7feb72125add955b5144ce642afe6a3e79a9e685..3dcae007baf43bc0ecb0694dab5468e73a0e730f 100644 (file)
@@ -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 is_elf64 = linux_pid_exe_is_elf_64_file (pid, &machine);
 
-  if (use_64bit < 0)
+  if (sizeof (void *) == 4)
+    {
+      if (is_elf64 > 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 (is_elf64 < 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;