Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [patch] Support bionic's jmp_buf.
@ 2012-05-21  0:36 Thiago Jung Bauermann
  2012-05-21 11:38 ` Pedro Alves
  0 siblings, 1 reply; 9+ messages in thread
From: Thiago Jung Bauermann @ 2012-05-21  0:36 UTC (permalink / raw)
  To: gdb-patches ml

Hello,

Android uses a libc (bionic) which is derived from BSD instead of glibc,
and stores the PC value at a different location in the jump buffer than
regular arm-linux. Also, since there's no PC mangling this code works
even without SystemTap probes.

I'm using the ELF interpreter field to identify an Android binary (the
program loader is /system/bin/linker). Also, I had to change
gdbarch_tdep->jb_pc to a function so that the code to determine which
kind of program we are dealing with runs when the value is actually
needed. This is because by the time arm_linux_init_abi is called
exec_bfd hasn't been set yet so there's no way to peek at the ELF
interpreter field.

This patch fixes gdb.base/longjmp.exp.

There are no regressions on arm-linux native, arm-linux remote or
i386-linux native.

Ok?

-- 
[]'s
Thiago Jung Bauermann
Linaro Toolchain Working Group


2012-05-20  Thiago Jung Bauermann  <thiago.bauermann@linaro.org>

	Support bionic's jmp_buf.
	* arm-linux-tdep.c (ARM_LINUX_JB_PC_ANDROID): New macro.
	(is_target_linux_android): New function.
	(arm_linux_jb_pc): Likewise.
	(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.
	* solib-svr4.c (find_program_interpreter): Remove static keyword.
	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..b9d67b0 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,54 @@ arm_stap_parse_special_token (struct gdbarch *gdbarch,
   return 1;
 }
 
+/* Determines whether the inferior is an Android application.  */
+
+static int
+is_target_linux_android (void)
+{
+  int ret = 0;
+  gdb_byte *interp;
+
+  interp = find_elf_program_interpreter ();
+  if (interp)
+    {
+      ret = !strcmp (interp, "/system/bin/linker");
+      xfree (interp);
+    }
+
+  return ret;
+}
+
+/* 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 (is_target_linux_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 +1261,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 df5dea7..d1aa6b5 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -9083,12 +9083,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;
 
@@ -10132,7 +10133,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.  */
@@ -10236,7 +10237,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/solib-svr4.c b/gdb/solib-svr4.c
index 69d3cb5..24f224f 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;
 
@@ -1520,7 +1520,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 */



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch] Support bionic's jmp_buf.
  2012-05-21  0:36 [patch] Support bionic's jmp_buf Thiago Jung Bauermann
@ 2012-05-21 11:38 ` Pedro Alves
  2012-05-21 17:59   ` Thiago Jung Bauermann
  0 siblings, 1 reply; 9+ messages in thread
From: Pedro Alves @ 2012-05-21 11:38 UTC (permalink / raw)
  To: Thiago Jung Bauermann; +Cc: gdb-patches ml

On 05/21/2012 01:35 AM, Thiago Jung Bauermann wrote:

> Hello,
> 
> Android uses a libc (bionic) which is derived from BSD instead of glibc,
> and stores the PC value at a different location in the jump buffer than
> regular arm-linux. Also, since there's no PC mangling this code works
> even without SystemTap probes.
> 
> I'm using the ELF interpreter field to identify an Android binary (the
> program loader is /system/bin/linker).


Urgh.  Isn't there a better way?  This doesn't work with shared libraries,
for starters.

But I think question number one is:

- Shouldn't there be an "Android" or "Bionic/Linux" OSABI instead
of abusing "GNU/Linux" ?

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch] Support bionic's jmp_buf.
  2012-05-21 11:38 ` Pedro Alves
@ 2012-05-21 17:59   ` Thiago Jung Bauermann
  2012-06-24 21:46     ` Thiago Jung Bauermann
  0 siblings, 1 reply; 9+ messages in thread
From: Thiago Jung Bauermann @ 2012-05-21 17:59 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches ml

Hello Pedro,

Thanks for the quick response.

On Mon, 2012-05-21 at 12:38 +0100, Pedro Alves wrote:
> On 05/21/2012 01:35 AM, Thiago Jung Bauermann wrote:
> > I'm using the ELF interpreter field to identify an Android binary (the
> > program loader is /system/bin/linker).
> 
> 
> Urgh.  Isn't there a better way?  This doesn't work with shared libraries,
> for starters.

There is. I thought of adding an Android flag to .note.ABI-tag and I
even have a patch ready which adds it to Android  binaries. I gave up on
it because I thought it was overkill but I can certainly use that if
using the interpreter field is a worse solution.

Regarding shared libraries, does it matter? If the executable uses
bionic, then the shared libraries can't be using something else, or can
they?

> But I think question number one is:
> 
> - Shouldn't there be an "Android" or "Bionic/Linux" OSABI instead
> of abusing "GNU/Linux" ?

I think it shouldn't, and I think it's not abuse. Android has the same
ABI as GNU/Linux, the differences are in implementation details outside
the scope of the ABI:

"Note that the AAPCS standard defines 'EABI' as a moniker used to
specify a _family_ of similar but distinct ABIs. Android follows the
little-endian ARM GNU/Linux ABI as documented in the following
document: 

http://www.codesourcery.com/gnu_toolchains/arm/arm_gnu_linux_abi.pdf

With the exception that wchar_t is only one byte. This should not matter
in practice since wchar_t is simply *not* really supported by the
Android platform anyway. This ABI does *not* support hardware-assisted
floating point computations. Instead, all FP operations are performed
through software helper functions that come from the compiler's libgcc.a
static library."

It also doesn't support C++ exceptions.


[1] http://www.kandroid.org/ndk/docs/CPU-ARCH-ABIS.html

-- 
[]'s
Thiago Jung Bauermann
Linaro Toolchain Working Group


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch] Support bionic's jmp_buf.
  2012-05-21 17:59   ` Thiago Jung Bauermann
@ 2012-06-24 21:46     ` Thiago Jung Bauermann
  2012-06-25 13:32       ` Yao Qi
  2012-06-27 10:18       ` Pedro Alves
  0 siblings, 2 replies; 9+ messages in thread
From: Thiago Jung Bauermann @ 2012-06-24 21:46 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches ml

On Mon, 2012-05-21 at 14:59 -0300, Thiago Jung Bauermann wrote:
> On Mon, 2012-05-21 at 12:38 +0100, Pedro Alves wrote:
> > On 05/21/2012 01:35 AM, Thiago Jung Bauermann wrote:
> > > I'm using the ELF interpreter field to identify an Android binary (the
> > > program loader is /system/bin/linker).
> > 
> > 
> > Urgh.  Isn't there a better way?  This doesn't work with shared libraries,
> > for starters.
> 
> There is. I thought of adding an Android flag to .note.ABI-tag and I
> even have a patch ready which adds it to Android  binaries. I gave up on
> it because I thought it was overkill but I can certainly use that if
> using the interpreter field is a worse solution.

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.

The patch below checks the .note.ABI-tag if it is present. If it is not,
then it will fall back to checking the interpreter field. WDYT?

-- 
[]'s
Thiago Jung Bauermann
Linaro Toolchain Working Group


2012-06-24  Thiago Jung Bauermann  <thiago.bauermann@linaro.org>

	Support bionic's jmp_buf.
	* arm-linux-tdep.c (ARM_LINUX_JB_PC_ANDROID): New macro.
	(is_target_linux_android): New function.
	(arm_linux_jb_pc): Likewise.
	(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.
	* osabi.c (check_note): Remove static keyword.
	* osabi.h (check_note): New prototype.
	* solib-svr4.c (find_program_interpreter): Remove static keyword.
	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..eac7602 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -33,6 +33,7 @@
 #include "tramp-frame.h"
 #include "breakpoint.h"
 #include "auxv.h"
+#include "elf/common.h"
 
 #include "arm-tdep.h"
 #include "arm-linux-tdep.h"
@@ -105,6 +106,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 +1180,85 @@ arm_stap_parse_special_token (struct gdbarch *gdbarch,
   return 1;
 }
 
+/* Determines whether the inferior is an Android application.  */
+
+static int
+is_target_linux_android (void)
+{
+  int ret = 0;
+  gdb_byte *interp;
+
+  if (exec_bfd
+      && bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour)
+    {
+      struct bfd_section *abi_tag;
+
+      abi_tag = bfd_get_section_by_name (exec_bfd, ".note.ABI-tag");
+      if (abi_tag != NULL)
+	{
+	  int sect_size = bfd_section_size (exec_bfd, abi_tag);
+	  gdb_byte *note;
+
+	  note = alloca (sect_size);
+	  bfd_get_section_contents (exec_bfd, abi_tag, note, 0, sect_size);
+
+	  /* Android's .note.ABI-tag has two 32 bit integers after the
+	     kernel version, so it's description size is 24 bytes.  */
+	  if (!check_note (exec_bfd, abi_tag, note, "GNU", 24, NT_GNU_ABI_TAG))
+	    return 0;
+
+	  /* Check the OS.  */
+	  if (bfd_h_get_32 (exec_bfd, note + 16) != GNU_ABI_TAG_LINUX)
+	    return 0;
+
+	  /* Check the the OS variant (1 means Android).  */
+	  if (bfd_h_get_32 (exec_bfd, note + 32) != 1)
+	    return 0;
+
+	  return 1;
+	}
+    }
+
+  interp = find_elf_program_interpreter ();
+  if (interp)
+    {
+      ret = !strcmp (interp, "/system/bin/linker");
+      xfree (interp);
+    }
+
+  return ret;
+}
+
+/* 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 (is_target_linux_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 +1293,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 df5dea7..d1aa6b5 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -9083,12 +9083,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;
 
@@ -10132,7 +10133,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.  */
@@ -10236,7 +10237,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/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 */



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch] Support bionic's jmp_buf.
  2012-06-24 21:46     ` Thiago Jung Bauermann
@ 2012-06-25 13:32       ` Yao Qi
  2012-06-25 17:55         ` Thiago Jung Bauermann
  2012-06-27 10:18       ` Pedro Alves
  1 sibling, 1 reply; 9+ messages in thread
From: Yao Qi @ 2012-06-25 13:32 UTC (permalink / raw)
  To: gdb-patches; +Cc: Thiago Jung Bauermann, Pedro Alves

On Sunday, June 24, 2012 06:46:15 PM Thiago Jung Bauermann wrote:
> +/* Determines whether the inferior is an Android application.  */
> +
> +static int
> +is_target_linux_android (void)

Looks this function is not arm-specific, so we can move it to linux-tdep.c.

-- 
Yao (齐尧)


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch] Support bionic's jmp_buf.
  2012-06-25 13:32       ` Yao Qi
@ 2012-06-25 17:55         ` Thiago Jung Bauermann
  2012-06-25 20:49           ` Schnell, Fabian
  0 siblings, 1 reply; 9+ messages in thread
From: Thiago Jung Bauermann @ 2012-06-25 17:55 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches, Pedro Alves

Hello,

On Mon, 2012-06-25 at 21:32 +0800, Yao Qi wrote:
> On Sunday, June 24, 2012 06:46:15 PM Thiago Jung Bauermann wrote:
> > +/* Determines whether the inferior is an Android application.  */
> > +
> > +static int
> > +is_target_linux_android (void)
> 
> Looks this function is not arm-specific, so we can move it to linux-tdep.c.

Thanks for your review.

Android is officially supported on ARM and x86. I don't know how GDB
fares on Android on x86, and at least for now it will only be used on
ARM (I don't have plans to work on Android on x86).

With that said, I'm happy to move to linux-tdep.c if that makes more
sense. I'll do the change before I commit or on the next iteration of
the patch if there is one.

-- 
[]'s
Thiago Jung Bauermann
Linaro Toolchain Working Group


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch] Support bionic's jmp_buf.
  2012-06-25 17:55         ` Thiago Jung Bauermann
@ 2012-06-25 20:49           ` Schnell, Fabian
  0 siblings, 0 replies; 9+ messages in thread
From: Schnell, Fabian @ 2012-06-25 20:49 UTC (permalink / raw)
  To: Thiago Jung Bauermann; +Cc: Yao Qi, gdb-patches, Pedro Alves

On 6/25/2012 10:54 AM, Thiago Jung Bauermann wrote:
> Hello,
>
> On Mon, 2012-06-25 at 21:32 +0800, Yao Qi wrote:
>> On Sunday, June 24, 2012 06:46:15 PM Thiago Jung Bauermann wrote:
>>> +/* Determines whether the inferior is an Android application.  */
>>> +
>>> +static int
>>> +is_target_linux_android (void)
>> Looks this function is not arm-specific, so we can move it to linux-tdep.c.
> Thanks for your review.
>
> Android is officially supported on ARM and x86. I don't know how GDB
> fares on Android on x86, and at least for now it will only be used on
> ARM (I don't have plans to work on Android on x86).
>
> With that said, I'm happy to move to linux-tdep.c if that makes more
> sense. I'll do the change before I commit or on the next iteration of
> the patch if there is one.
>
Looking at the original patch, the code is not required for bionic on x86.
Yet, to have this function in a shared location might make it easier to 
code dependencies in the future.

- Fabian


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch] Support bionic's jmp_buf.
  2012-06-24 21:46     ` Thiago Jung Bauermann
  2012-06-25 13:32       ` Yao Qi
@ 2012-06-27 10:18       ` Pedro Alves
  2012-07-04 21:08         ` Thiago Jung Bauermann
  1 sibling, 1 reply; 9+ messages in thread
From: Pedro Alves @ 2012-06-27 10:18 UTC (permalink / raw)
  To: Thiago Jung Bauermann; +Cc: gdb-patches ml

On 06/24/2012 10:46 PM, Thiago Jung Bauermann wrote:>>> Urgh.  Isn't there a better way?  This doesn't work with shared libraries,
>>> > > for starters.
>> >
>> > There is. I thought of adding an Android flag to .note.ABI-tag and I
>> > even have a patch ready which adds it to Android  binaries. I gave up on
>> > it because I thought it was overkill but I can certainly use that if
>> > using the interpreter field is a worse solution.
> 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.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [patch] Support bionic's jmp_buf.
  2012-06-27 10:18       ` Pedro Alves
@ 2012-07-04 21:08         ` Thiago Jung Bauermann
  0 siblings, 0 replies; 9+ messages in thread
From: Thiago Jung Bauermann @ 2012-07-04 21:08 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches ml, Yao Qi, Schnell, Fabian

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 */



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-07-04 21:08 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-21  0:36 [patch] Support bionic's jmp_buf Thiago Jung Bauermann
2012-05-21 11:38 ` Pedro Alves
2012-05-21 17:59   ` Thiago Jung Bauermann
2012-06-24 21:46     ` Thiago Jung Bauermann
2012-06-25 13:32       ` Yao Qi
2012-06-25 17:55         ` Thiago Jung Bauermann
2012-06-25 20:49           ` Schnell, Fabian
2012-06-27 10:18       ` Pedro Alves
2012-07-04 21:08         ` Thiago Jung Bauermann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox