This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] Support bionic's jmp_buf.


On Wed, 2012-06-27 at 11:18 +0100, Pedro Alves wrote:
> On 06/24/2012 10:46 PM, Thiago Jung Bauermann wrote:
> > I submitted a patch to bionic which adds a .note.ABI-tag to Android
> > binaries:
> >
> > https://android-review.googlesource.com/37590
> > The note has a flag which is set to 1 if the binary is for the Android
> > platform.
> > 
> > The patch was accepted by the Google engineers and applied to their
> > internal tree. It wasn't merged yet to the AOSP tree because of
> > conflicts with some of their internal patches, but will be in the near
> > future.
> 
> Thank you very much for persevering.  I think that using "GNU" as
> ABI_VENDOR for Android isn't the best thing to do, but from skimming
> the binutils@ list I see you're already addressing that.

Right. I updated the bionic patch in the link above to
use .note.android.ident, which is similar to .note.netbsd.ident
and .note.openbsd.ident.

This patch uses that note, and also moves is_target_linux_android to
linux-tdep.c. The function is now called linux_is_target_android for
consistency with other functions in that file.

-- 
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center


2012-07-04  Thiago Jung Bauermann  <thiago.bauermann@linaro.org>

	Support bionic's jmp_buf.
	* arm-linux-tdep.c (ARM_LINUX_JB_PC_ANDROID): New macro.
	(arm_linux_jb_pc): New function.
	(arm_linux_init_abi): Set tdep->jb_pc to arm_linux_jb_pc
	instead of determining the jb_pc value right away.
	* arm-tdep.c (arm_get_longjmp_target): Call tdep->jb_pc.
	(arm_gdbarch_init): tdep->jb_pc is now a pointer. Assign it
	and test its value accordingly.
	* arm-tdep.h (struct gdbarch_tdep): Change jb_pc to a
	function pointer.
	* arm-wince-tdep.c (arm_wince_jb_pc): New function.
	(arm_wince_init_abi): Set tdep->jb_pc to arm_wince_jb_pc.
	* armnbsd-tdep.c (arm_netbsd_jb_pc): New function.
	(arm_netbsd_init_abi_common): Set tdep->jb_pc to arm_netbsd_jb_pc.
	* armobsd-tdep.c (arm_obsd_jb_pc): New function.
	(armobsd_init_abi): Set tdep->jb_pc to arm_obsd_jb_pc.
	* linux-tdep.c (NT_ANDROID_IDENT): New macro.
	(linux_is_target_android): New function.
	* linux-tdep.h (linux_is_target_android): New prototype.
	* osabi.c (check_note): Make function non-static.
	* osabi.h (check_note): New prototype.
	* solib-svr4.c (find_program_interpreter): Make function non-static.
	Rename to ...
	(find_elf_program_interpreter): ... this.
	* solib-svr4.h (find_program_interpreter): New prototype.


diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index f4eaa5c..d35cfd3 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -105,6 +105,7 @@ static const char arm_linux_thumb2_le_breakpoint[] = { 0xf0, 0xf7, 0x00, 0xa0 };
 #define ARM_LINUX_JB_ELEMENT_SIZE	INT_REGISTER_SIZE
 #define ARM_LINUX_JB_PC_FPA		21
 #define ARM_LINUX_JB_PC_EABI		9
+#define ARM_LINUX_JB_PC_ANDROID		29
 
 /*
    Dynamic Linking on ARM GNU/Linux
@@ -1178,6 +1179,36 @@ arm_stap_parse_special_token (struct gdbarch *gdbarch,
   return 1;
 }
 
+/* Implements the gdbarch_tdep.jb_pc function in arm-tdep.h.  */
+
+static CORE_ADDR
+arm_linux_jb_pc (struct gdbarch_tdep *tdep)
+{
+  int jb_pc;
+
+  switch (tdep->fp_model)
+    {
+    case ARM_FLOAT_FPA:
+      jb_pc = ARM_LINUX_JB_PC_FPA;
+      break;
+    case ARM_FLOAT_SOFT_FPA:
+    case ARM_FLOAT_SOFT_VFP:
+    case ARM_FLOAT_VFP:
+      jb_pc = ARM_LINUX_JB_PC_EABI;
+      break;
+    default:
+      internal_error
+	(__FILE__, __LINE__,
+         _("arm_linux_init_abi: Floating point model not supported"));
+      break;
+    }
+
+  if (linux_is_target_android ())
+    jb_pc = ARM_LINUX_JB_PC_ANDROID;
+
+  return jb_pc;
+}
+
 static void
 arm_linux_init_abi (struct gdbarch_info info,
 		    struct gdbarch *gdbarch)
@@ -1212,22 +1243,7 @@ arm_linux_init_abi (struct gdbarch_info info,
   if (tdep->fp_model == ARM_FLOAT_AUTO)
     tdep->fp_model = ARM_FLOAT_FPA;
 
-  switch (tdep->fp_model)
-    {
-    case ARM_FLOAT_FPA:
-      tdep->jb_pc = ARM_LINUX_JB_PC_FPA;
-      break;
-    case ARM_FLOAT_SOFT_FPA:
-    case ARM_FLOAT_SOFT_VFP:
-    case ARM_FLOAT_VFP:
-      tdep->jb_pc = ARM_LINUX_JB_PC_EABI;
-      break;
-    default:
-      internal_error
-	(__FILE__, __LINE__,
-         _("arm_linux_init_abi: Floating point model not supported"));
-      break;
-    }
+  tdep->jb_pc = arm_linux_jb_pc;
   tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE;
 
   set_solib_svr4_fetch_link_map_offsets
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 568ace5..f925d44 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -9086,12 +9086,13 @@ arm_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  CORE_ADDR jb_addr;
+  CORE_ADDR jb_addr, jb_pc;
   char buf[INT_REGISTER_SIZE];
-  
+
   jb_addr = get_frame_register_unsigned (frame, ARM_A1_REGNUM);
+  jb_pc = tdep->jb_pc (tdep);
 
-  if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf,
+  if (target_read_memory (jb_addr + jb_pc * tdep->jb_elt_size, buf,
 			  INT_REGISTER_SIZE))
     return 0;
 
@@ -10135,7 +10136,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* This should be low enough for everything.  */
   tdep->lowest_pc = 0x20;
-  tdep->jb_pc = -1;	/* Longjump support not enabled by default.  */
+  tdep->jb_pc = NULL;	/* Longjump support not enabled by default.  */
 
   /* The default, for both APCS and AAPCS, is to return small
      structures in registers.  */
@@ -10239,7 +10240,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (tdep->fp_model == ARM_FLOAT_AUTO)
     tdep->fp_model = ARM_FLOAT_SOFT_FPA;
 
-  if (tdep->jb_pc >= 0)
+  if (tdep->jb_pc != NULL)
     set_gdbarch_get_longjmp_target (gdbarch, arm_get_longjmp_target);
 
   /* Floating point sizes and format.  */
diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h
index 97596d5..b95d548 100644
--- a/gdb/arm-tdep.h
+++ b/gdb/arm-tdep.h
@@ -185,9 +185,9 @@ struct gdbarch_tdep
   const char *thumb2_breakpoint;
   int thumb2_breakpoint_size;
 
-  int jb_pc;			/* Offset to PC value in jump buffer.
-				   If this is negative, longjmp support
-				   will be disabled.  */
+  /* Return offset to PC value in jump buffer.  If this is NULL, longjmp
+     support will be disabled.  */
+  CORE_ADDR (*jb_pc) (struct gdbarch_tdep *tdep);
   size_t jb_elt_size;		/* And the size of each entry in the buf.  */
 
   /* Convention for returning structures.  */
diff --git a/gdb/arm-wince-tdep.c b/gdb/arm-wince-tdep.c
index 5bc6473..ce04ba0 100644
--- a/gdb/arm-wince-tdep.c
+++ b/gdb/arm-wince-tdep.c
@@ -111,6 +111,14 @@ arm_wince_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
   return pc;
 }
 
+/* Implements the gdbarch_tdep.jb_pc function in arm-tdep.h.  */
+
+static CORE_ADDR
+arm_wince_jb_pc (struct gdbarch_tdep *tdep)
+{
+  return ARM_WINCE_JB_PC;
+}
+
 static void
 arm_wince_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -124,7 +132,7 @@ arm_wince_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   tdep->fp_model = ARM_FLOAT_SOFT_VFP;
 
-  tdep->jb_pc = ARM_WINCE_JB_PC;
+  tdep->jb_pc = arm_wince_jb_pc;
   tdep->jb_elt_size = ARM_WINCE_JB_ELEMENT_SIZE;
 
   /* On ARM WinCE char defaults to signed.  */
diff --git a/gdb/armnbsd-tdep.c b/gdb/armnbsd-tdep.c
index 19aa000..144bd85 100644
--- a/gdb/armnbsd-tdep.c
+++ b/gdb/armnbsd-tdep.c
@@ -36,6 +36,14 @@ static const char arm_nbsd_arm_be_breakpoint[] = {0xe6, 0x00, 0x00, 0x11};
 static const char arm_nbsd_thumb_le_breakpoint[] = {0xfe, 0xde};
 static const char arm_nbsd_thumb_be_breakpoint[] = {0xde, 0xfe};
 
+/* Implements the gdbarch_tdep.jb_pc function in arm-tdep.h.  */
+
+static CORE_ADDR
+arm_netbsd_jb_pc (struct gdbarch_tdep *tdep)
+{
+  return ARM_NBSD_JB_PC;
+}
+
 static void
 arm_netbsd_init_abi_common (struct gdbarch_info info,
 			    struct gdbarch *gdbarch)
@@ -64,7 +72,7 @@ arm_netbsd_init_abi_common (struct gdbarch_info info,
 		      _("arm_gdbarch_init: bad byte order for float format"));
     }
 
-  tdep->jb_pc = ARM_NBSD_JB_PC;
+  tdep->jb_pc = arm_netbsd_jb_pc;
   tdep->jb_elt_size = ARM_NBSD_JB_ELEMENT_SIZE;
 
   /* Single stepping.  */
diff --git a/gdb/armobsd-tdep.c b/gdb/armobsd-tdep.c
index fab4e42..e48eeaa 100644
--- a/gdb/armobsd-tdep.c
+++ b/gdb/armobsd-tdep.c
@@ -74,6 +74,14 @@ static const struct tramp_frame armobsd_sigframe =
 static const char arm_obsd_thumb_le_breakpoint[] = {0xfe, 0xdf};
 static const char arm_obsd_thumb_be_breakpoint[] = {0xdf, 0xfe};
 
+/* Implements the gdbarch_tdep.jb_pc function in arm-tdep.h.  */
+
+static CORE_ADDR
+armobsd_jb_pc (struct gdbarch_tdep *tdep)
+{
+  return 24;
+}
+
 static void
 armobsd_init_abi (struct gdbarch_info info,
 		  struct gdbarch *gdbarch)
@@ -90,7 +98,7 @@ armobsd_init_abi (struct gdbarch_info info,
     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
   set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
 
-  tdep->jb_pc = 24;
+  tdep->jb_pc = armobsd_jb_pc;
   tdep->jb_elt_size = 4;
 
   set_gdbarch_regset_from_core_section
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index b6f2efb..42da96c 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -30,6 +30,8 @@
 #include "elf-bfd.h"            /* for elfcore_write_* */
 #include "inferior.h"
 #include "cli/cli-utils.h"
+#include "osabi.h"
+#include "solib-svr4.h"
 
 #include <ctype.h>
 
@@ -188,6 +190,49 @@ linux_has_shared_address_space (struct gdbarch *gdbarch)
   return target_is_uclinux;
 }
 
+/* Type of the .note.android.ident note.  Note vendor is "Android".  */
+#define NT_ANDROID_IDENT		1
+
+/* Determines whether the inferior is an Android application.  */
+
+int
+linux_is_target_android (void)
+{
+  int ret = 0;
+  gdb_byte *interp;
+
+  if (exec_bfd
+      && bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour)
+    {
+      struct bfd_section *ident;
+
+      ident = bfd_get_section_by_name (exec_bfd, ".note.android.ident");
+      if (ident != NULL)
+	{
+	  int sect_size = bfd_section_size (exec_bfd, ident);
+	  gdb_byte *note;
+
+	  note = alloca (sect_size);
+	  bfd_get_section_contents (exec_bfd, ident, note, 0, sect_size);
+
+	  /* Android's ident note has one 32-bit integer specifying the
+	     API level expected by the application.  We don't need to
+	     check it yet.  */
+	  return check_note (exec_bfd, ident, note, "Android", 4,
+			     NT_ANDROID_IDENT);
+	}
+    }
+
+  interp = find_elf_program_interpreter ();
+  if (interp)
+    {
+      ret = !strcmp (interp, "/system/bin/linker");
+      xfree (interp);
+    }
+
+  return ret;
+}
+
 /* This is how we want PTIDs from core files to be printed.  */
 
 static char *
diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h
index b211b53..1dab1c7 100644
--- a/gdb/linux-tdep.h
+++ b/gdb/linux-tdep.h
@@ -36,4 +36,6 @@ struct type *linux_get_siginfo_type (struct gdbarch *);
 
 extern void linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch);
 
+extern int linux_is_target_android (void);
+
 #endif /* linux-tdep.h */
diff --git a/gdb/osabi.c b/gdb/osabi.c
index faffe30..9d3eef4 100644
--- a/gdb/osabi.c
+++ b/gdb/osabi.c
@@ -372,7 +372,7 @@ gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
 /* Return non-zero if NOTE matches NAME, DESCSZ and TYPE.  */
 
-static int
+int
 check_note (bfd *abfd, asection *sect, const char *note,
 	    const char *name, unsigned long descsz, unsigned long type)
 {
diff --git a/gdb/osabi.h b/gdb/osabi.h
index ced2fa5..ec3b948 100644
--- a/gdb/osabi.h
+++ b/gdb/osabi.h
@@ -54,4 +54,8 @@ const char *gdbarch_osabi_name (enum gdb_osabi);
    via bfd_map_over_sections.  */
 void generic_elf_osabi_sniff_abi_tag_sections (bfd *, asection *, void *);
 
+/* Return non-zero if NOTE matches NAME, DESCSZ and TYPE.  */
+int check_note (bfd *abfd, asection *sect, const char *note,
+		const char *name, unsigned long descsz, unsigned long type);
+
 #endif /* OSABI_H */
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 307e483..cd3be82 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -496,8 +496,8 @@ read_program_header (int type, int *p_sect_size, int *p_arch_size)
 
 
 /* Return program interpreter string.  */
-static gdb_byte *
-find_program_interpreter (void)
+gdb_byte *
+find_elf_program_interpreter (void)
 {
   gdb_byte *buf = NULL;
 
@@ -1528,7 +1528,7 @@ enable_break (struct svr4_info *info, int from_tty)
 
   /* Find the program interpreter; if not found, warn the user and drop
      into the old breakpoint at symbol code.  */
-  interp_name = find_program_interpreter ();
+  interp_name = find_elf_program_interpreter ();
   if (interp_name)
     {
       CORE_ADDR load_addr = 0;
diff --git a/gdb/solib-svr4.h b/gdb/solib-svr4.h
index f9a02c9..87f088d 100644
--- a/gdb/solib-svr4.h
+++ b/gdb/solib-svr4.h
@@ -84,4 +84,7 @@ extern struct link_map_offsets *svr4_lp64_fetch_link_map_offsets (void);
    SVR4 run time loader.  */
 int svr4_in_dynsym_resolve_code (CORE_ADDR pc);
 
+/* Return program interpreter string.  */
+gdb_byte *find_elf_program_interpreter (void);
+
 #endif /* solib-svr4.h */



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]