The full diff between AOSP's gdb.git/gdb-7.3.x/gdb and FSF gdb-7.3/gdb is much bigger. This is a version edited to contain only Android platform enablement and bugfixes.

The other changes are Googleisms (as they put it), higher level changes (mostly symbol handling/DWARF related) and backports.

For each hunk, I put my comments in lines starting with ===.

diff -pruN gdb.git/gdb/arm-linux-tdep.c android/gdb.git/gdb-7.3.x/gdb/arm-linux-tdep.c
--- gdb.git/gdb/arm-linux-tdep.c        2012-03-27 12:26:22.795518560 -0300
+++ android/gdb.git/gdb-7.3.x/gdb/arm-linux-tdep.c      2012-02-22 21:59:49.424403584 -0200
@@ -32,6 +32,7 @@
 #include "regset.h"
 #include "trad-frame.h"
 #include "tramp-frame.h"
+#include "frame-unwind.h"  /* for Android */
 #include "breakpoint.h"
 
 #include "arm-tdep.h"

=== Part of the Signal handler frame sniffer. Not needed upstream.

@@ -96,6 +97,7 @@ static const char arm_linux_thumb2_le_br
 #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_ANDROID_JB_PC               24
 
 /*
    Dynamic Linking on ARM GNU/Linux

=== Part of the longjmp buffer support. Submitted upstream.

@@ -411,6 +413,69 @@ static struct tramp_frame arm_linux_rt_s
   arm_linux_rt_sigreturn_init
 };
 
+static void
+arm_android_sigreturn_init (struct frame_info *this_frame,
+                           struct trad_frame_cache *this_cache,
+                           CORE_ADDR func)
+{
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  CORE_ADDR sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);
+  ULONGEST uc_flags = read_memory_unsigned_integer (sp, 4, byte_order);
+
+  if (uc_flags == ARM_NEW_SIGFRAME_MAGIC)
+    arm_linux_sigtramp_cache (this_frame, this_cache, func,
+                             ARM_UCONTEXT_SIGCONTEXT
+                             + ARM_SIGCONTEXT_R0);
+  else
+    arm_linux_sigtramp_cache (this_frame, this_cache, func,
+                             ARM_SIGCONTEXT_R0);
+}
+
+static void
+arm_android_sigreturn_frame_this_id (struct frame_info *this_frame,
+                                    void **this_cache,
+                                    struct frame_id *this_id)
+{
+  struct trad_frame_cache *trad_cache = *this_cache;
+  trad_frame_get_id (trad_cache, this_id);
+}
+
+static struct value *
+arm_android_sigreturn_frame_prev_register (struct frame_info *this_frame,
+                                          void **this_cache,
+                                          int prev_regnum)
+{
+  struct trad_frame_cache *trad_cache = *this_cache;
+  return trad_frame_get_register (trad_cache, this_frame, prev_regnum);
+}
+
+static int
+arm_android_sigreturn_frame_sniffer (const struct frame_unwind *self,
+                                    struct frame_info *this_frame,
+                                    void **this_cache)
+{
+  CORE_ADDR pc = get_frame_pc (this_frame);
+  struct trad_frame_cache *trad_cache;
+
+  if (pc != 0xffff0500)
+    return 0;
+
+  trad_cache = trad_frame_cache_zalloc (this_frame);
+  arm_android_sigreturn_init (this_frame, trad_cache, pc);
+  (*this_cache) = trad_cache;
+  return 1;
+}
+
+static struct frame_unwind arm_android_sigreturn_tramp_frame = {
+  SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
+  arm_android_sigreturn_frame_this_id,
+  arm_android_sigreturn_frame_prev_register,
+  NULL,
+  arm_android_sigreturn_frame_sniffer
+};
+
 static struct tramp_frame arm_eabi_linux_sigreturn_tramp_frame = {
   SIGTRAMP_FRAME,
   4,

=== Part of the Signal handler frame sniffer. Not needed upstream.

@@ -1009,6 +1074,10 @@ arm_linux_init_abi (struct gdbarch_info
          _("arm_linux_init_abi: Floating point model not supported"));
       break;
     }
+
+  if (is_target_linux_android ())
+    tdep->jb_pc = ARM_ANDROID_JB_PC;
+
   tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE;
 
   set_solib_svr4_fetch_link_map_offsets

=== Part of the longjmp buffer support. Submitted upstream.

@@ -1025,6 +1094,15 @@ arm_linux_init_abi (struct gdbarch_info
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                              svr4_fetch_objfile_link_map);
 
+  if (is_target_linux_android ())
+    /* This is incomplete, we can't singlestep through the handler back to
+       the interrupted code, address 0xffff0500 is inaccessible.
+       This is really a temp hack until there's libc additions to put the
+       trampoline code in user space.  */
+    frame_unwind_prepend_unwinder (gdbarch,
+                                   &arm_android_sigreturn_tramp_frame);
+  else
+  { /* This indentation is on purpose to minimize whitespace changes.  */
   tramp_frame_prepend_unwinder (gdbarch,
                                &arm_linux_sigreturn_tramp_frame);
   tramp_frame_prepend_unwinder (gdbarch,

=== Part of the Signal handler frame sniffer. Not needed upstream.

@@ -1037,6 +1115,7 @@ arm_linux_init_abi (struct gdbarch_info
                                &arm_linux_restart_syscall_tramp_frame);
   tramp_frame_prepend_unwinder (gdbarch,
                                &arm_kernel_linux_restart_syscall_tramp_frame);
+  }
 
   /* Core file support.  */
   set_gdbarch_regset_from_core_section (gdbarch,
diff -pruN gdb.git/gdb/arm-tdep.c android/gdb.git/gdb-7.3.x/gdb/arm-tdep.c

=== Part of the Signal handler frame sniffer. Not needed upstream.

--- gdb.git/gdb/arm-tdep.c      2012-03-27 12:26:22.799518600 -0300
+++ android/gdb.git/gdb-7.3.x/gdb/arm-tdep.c    2012-02-22 21:59:49.424403584 -0200
@@ -1351,6 +1351,175 @@ arm_skip_stack_protector(CORE_ADDR pc, s
     return pc + offset + 8;
 }
 
+/* Subroutine of skip_gcc_pic_assignment to simplify it.
+   After establishing that we're at a gcc pic assignment,
+   return a possibly adjusted value for the end of the prologue.
+   PIC_ASSIGNMENT_LENGTH is the total length of insns that assign
+   the pic reg.  */
+
+static CORE_ADDR
+skip_gcc_pic_assignment_1 (struct gdbarch *gdbarch,
+                           CORE_ADDR func_addr, CORE_ADDR post_prologue_pc,
+                           int pic_assignment_length)
+{
+  struct symtab_and_line func_addr_sal, post_prologue_sal, sal2;
+
+  func_addr_sal = find_pc_line (func_addr, 0);
+  sal2 = find_pc_line (post_prologue_pc + pic_assignment_length, 0);
+  /* Catch the case of being in the middle of the prologue.  */
+  if (func_addr_sal.line != 0
+      && func_addr_sal.line == sal2.line)
+    post_prologue_pc = sal2.end;
+  /* Catch the case of being at the end of the prologue.  */
+  else
+  {
+    post_prologue_sal = find_pc_line (post_prologue_pc, 0);
+    if (post_prologue_sal.line != 0
+          && sal2.line != 0
+        && sal2.line <= post_prologue_sal.line)
+      post_prologue_pc = post_prologue_sal.end;
+  }
+
+  return post_prologue_pc;
+}
+
+/* Subroutine of skip_gcc_pic_assignment to simplify it.
+   Skip version 1 of a thumb pic register assignment.
+   The result is the length of the code in bytes or zero if not for pic.  */
+
+static int
+skip_gcc_thumb_pic_assignment_1 (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
+  unsigned short insn;
+  unsigned int reg;
+
+  insn = read_memory_unsigned_integer (addr, 2, byte_order_for_code);
+  if ((insn & 0xf800) != 0x4800) /* ldr rN,[pc,foo] */
+    return 0;
+
+  reg = (insn >> 8) & 7;
+  insn = read_memory_unsigned_integer (addr + 2, 2, byte_order_for_code);
+  if ((insn & 0xffff)
+      /* Note: We know reg < 8 here.  */
+      != (0x4400 + 0x78 /* pc */ + reg)) /* add rN, pc */
+    return 0;
+
+  return 4;
+}
+
+static int
+skip_gcc_arm_pic_assignment_1 (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
+  unsigned int insn;
+  unsigned int reg;
+
+  insn = read_memory_unsigned_integer (addr, 4, byte_order_for_code);
+  if ((insn & 0xffff0000)
+      != (0xe5900000 + 0xf0000 /*pc*/)) /* ldr rN,[pc,foo] */
+    return 0;
+
+  reg = (insn >> 12) & 15;
+  insn = read_memory_unsigned_integer (addr + 4, 4, byte_order_for_code);
+  if ((insn & 0xffffffff)
+      /* add rN, pc, rN */
+      != (0xe0800000 + 0xf0000 /*pc*/ + (reg << 12) + reg))
+    return 0;
+
+  return 8;
+}
+
+/* Subroutine of skip_gcc_pic_assignment to simplify it.
+   Skip version 2 of an arm pic register assignment.
+   The result is the length of the code in bytes or zero if not for pic.  */
+
+static int
+skip_gcc_arm_pic_assignment_2 (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
+  unsigned int insn;
+  unsigned int regM, regN, regX, offset;
+
+  insn = read_memory_unsigned_integer (addr, 4, byte_order_for_code);
+  if ((insn & 0xffff0000)
+      != (0xe5900000 + 0xf0000 /*pc*/)) /* ldr rM,[pc,foo] */
+    return 0;
+
+  regM = (insn >> 12) & 15;
+  insn = read_memory_unsigned_integer (addr + 4, 4, byte_order_for_code);
+  if ((insn & 0xfff0f000)
+      != (0xe5000000 + (regM << 12))) /* str rM,[rX,-offset] */
+    return 0;
+  regX = (insn >> 16) & 15;
+  offset = insn & 4095;
+
+  insn = read_memory_unsigned_integer (addr + 8, 4, byte_order_for_code);
+  if ((insn & 0xffff0fff)
+      != (0xe5100000 + (regX << 16) + offset)) /* ldr rN,[rX,-offset] */
+    return 0;
+
+  regN = (insn >> 12) & 15;
+  insn = read_memory_unsigned_integer (addr + 12, 4, byte_order_for_code);
+  if ((insn & 0xffffffff)
+      /* add rN, pc, rN */
+      != (0xe0800000 + 0xf0000 /*pc*/ + (regN << 12) + regN))
+    return 0;
+
+  insn = read_memory_unsigned_integer (addr + 16, 4, byte_order_for_code);
+  if ((insn & 0xffffffff)
+      != (0xe5000000 + (regX << 16) + (regN << 12) + offset)) /* str rN,[rX,-offset] \
+                                                               */
+    return 0;
+
+  return 20;
+}
+
+/* Subroutine of arm_skip_prologue to simplify it.
+   Compensate for GCC 4.4.0 inserting pic register initialization in the
+   middle of the prologue with a line number outside the prologue.
+   This breaks skip_prologue_using_sal.
+   FUNC_ADDR is the start_pc result of find_pc_partial_function.
+   POST_PROLOGUE_PC is the pc returned by skip_prologue_using_sal.
+   The result is the new post-prologue-pc to use.
+
+   Two variations of loading the pic register have been seen:
+
+   (1) ldr rN,[pc,foo]
+       add rN, pc, rN
+
+   (2) ldr rM, [pc, foo]
+       str rM, [rX, offset]
+       ldr rN, [rX, offset]
+       add rN, pc, rN
+       str rN, [rX, offset]
+*/
+
+static CORE_ADDR
+skip_gcc_pic_assignment (struct gdbarch *gdbarch,
+                         CORE_ADDR func_addr, CORE_ADDR post_prologue_pc)
+{
+  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
+  unsigned int length;
+
+  if (arm_pc_is_thumb (gdbarch, func_addr))
+  {
+    length = skip_gcc_thumb_pic_assignment_1 (gdbarch, post_prologue_pc);
+  }
+  else
+  {
+    length = skip_gcc_arm_pic_assignment_1 (gdbarch, post_prologue_pc);
+    if (length == 0)
+      length = skip_gcc_arm_pic_assignment_2 (gdbarch, post_prologue_pc);
+  }
+
+  if (length != 0)
+    post_prologue_pc =
+        skip_gcc_pic_assignment_1 (gdbarch, func_addr, post_prologue_pc, length);
+
+  return post_prologue_pc;
+}
+
 /* Advance the PC across any function entry prologue instructions to
    reach some "real" code.
 

=== Part of the GCC 4.4.0 prologue fixes. Not needed upstream.

@@ -1388,6 +1557,12 @@ arm_skip_prologue (struct gdbarch *gdbar
        post_prologue_pc
          = arm_skip_stack_protector (post_prologue_pc, gdbarch);
 
+      if (post_prologue_pc && is_target_linux_android ())
+        /* GCC will move the setting of the pic register into the
+           middle of the prologue using line numbers from the original
+           location.  Compensate.  */
+        post_prologue_pc = skip_gcc_pic_assignment (gdbarch, func_addr,
+                                                    post_prologue_pc);
 
       /* GCC always emits a line note before the prologue and another
         one after, even if the two are at the same address or on the

=== Part of the GCC 4.4.0 prologue fixes. Not needed upstream.

diff -pruN gdb.git/gdb/breakpoint.c android/gdb.git/gdb-7.3.x/gdb/breakpoint.c
--- gdb.git/gdb/breakpoint.c    2012-03-27 12:26:22.819518837 -0300
+++ android/gdb.git/gdb-7.3.x/gdb/breakpoint.c  2012-02-22 21:59:49.432403660 -0200
@@ -12953,6 +12991,10 @@ hardware.)"),
 
   can_use_hw_watchpoints = 1;
 
+  /* For android, until h/w watchpoints are supported.  */
+  if (is_target_linux_android ())
+    can_use_hw_watchpoints = 0;
+
   /* Tracepoint manipulation commands.  */
 
   c = add_com ("trace", class_breakpoint, trace_command, _("\
diff -pruN gdb.git/gdb/defs.h android/gdb.git/gdb-7.3.x/gdb/defs.h

=== Hardcoding lack of support for hardware watchpoints. Not needed upstream.

--- gdb.git/gdb/defs.h  2012-03-27 12:26:22.939520223 -0300
+++ android/gdb.git/gdb-7.3.x/gdb/defs.h        2012-02-22 21:59:49.484404187 -0200
@@ -611,6 +617,9 @@ extern int input_from_terminal_p (void);
 
 extern int info_verbose;
 
+/* Test to see if target is Android  */
+extern int is_target_linux_android (void);
+
 /* From printcmd.c */
 
 extern void set_next_address (struct gdbarch *, CORE_ADDR);
diff -pruN gdb.git/gdb/gdbserver/inferiors.c android/gdb.git/gdb-7.3.x/gdb/gdbserver/inferiors.c

=== Part of the longjmp buffer support. Submitted upstream.

--- gdb.git/gdb/gdbserver/inferiors.c   2012-03-27 12:26:23.155522729 -0300
+++ android/gdb.git/gdb-7.3.x/gdb/gdbserver/inferiors.c 2012-02-22 21:59:49.680406155 -0200
@@ -387,14 +387,22 @@ unloaded_dll (const char *name, CORE_ADD
 #define clear_list(LIST) \
   do { (LIST)->head = (LIST)->tail = NULL; } while (0)
 
+/* Clear ALL_DLLS.  */
+
 void
-clear_inferiors (void)
+clear_all_dlls (void)
 {
-  for_each_inferior (&all_threads, free_one_thread);
   for_each_inferior (&all_dlls, free_one_dll);
+  clear_list (&all_dlls);
+}
 
+void
+clear_inferiors (void)
+{
+  for_each_inferior (&all_threads, free_one_thread);
   clear_list (&all_threads);
-  clear_list (&all_dlls);
+
+  clear_all_dlls ();
 
   current_inferior = NULL;
 }
diff -pruN gdb.git/gdb/gdbserver/linux-low.c android/gdb.git/gdb-7.3.x/gdb/gdbserver/linux-low.c

=== Part of the linux_refresh_libraries / clear_all_dlls patch. Not needed upstream.

--- gdb.git/gdb/gdbserver/linux-low.c   2012-03-27 12:26:23.159522769 -0300
+++ android/gdb.git/gdb-7.3.x/gdb/gdbserver/linux-low.c 2012-03-21 19:34:44.696656333 -0300
@@ -4184,6 +4184,14 @@ linux_test_for_tracefork (void)
 
   linux_supports_tracefork_flag = 0;
 
+#ifdef __ANDROID__
+  /* Setting linux_supports_tracefork_flag = 0 means we use thread events.
+     All the necessary thread event support doesn't currently exist on android,
+     and android can trace forks anyway.  */
+  linux_supports_tracefork_flag = 1;
+  return;
+#endif
+
 #if !(defined(__UCLIBC__) && defined(HAS_NOMMU))
 
   child_pid = fork ();

=== Thread events vs tracing fork. Not needed upstream.

@@ -5107,6 +5115,312 @@ linux_emit_ops (void)
     return NULL;
 }
 
+/* Clear and refresh ALL_DLLS list.  */
+
+static void
+linux_refresh_libraries (void)
+{
+  struct process_info_private *const priv = current_process ()->private;
+  char filename[PATH_MAX];
+  int pid, is_elf64, ptr_size, r_version;
+  CORE_ADDR lm_addr, lm_prev, l_name, l_addr, l_next, l_prev;
+
+  static const struct link_map_offsets lmo_32bit_offsets =
+    {
+      0,     /* r_version offset. */
+      4,     /* r_debug.r_map offset.  */
+      0,     /* l_addr offset in link_map.  */
+      4,     /* l_name offset in link_map.  */
+      12,    /* l_next offset in link_map.  */
+      16     /* l_prev offset in link_map.  */
+    };
+
+  static const struct link_map_offsets lmo_64bit_offsets =
+    {
+      0,     /* r_version offset. */
+      8,     /* r_debug.r_map offset.  */
+      0,     /* l_addr offset in link_map.  */
+      8,     /* l_name offset in link_map.  */
+      24,    /* l_next offset in link_map.  */
+      32     /* l_prev offset in link_map.  */
+    };
+  const struct link_map_offsets *lmo;
+
+  pid = lwpid_of (get_thread_lwp (current_inferior));
+  xsnprintf (filename, sizeof filename, "/proc/%d/exe", pid);
+  is_elf64 = elf_64_file_p (filename);
+  lmo = is_elf64 ? &lmo_64bit_offsets : &lmo_32bit_offsets;
+  ptr_size = is_elf64 ? 8 : 4;
+
+  if (priv->r_debug == 0)
+    priv->r_debug = get_r_debug (pid, is_elf64);
+
+  if (priv->r_debug == (CORE_ADDR) -1 || priv->r_debug == 0)
+    return;
+
+  r_version = 0;
+  if (linux_read_memory (priv->r_debug + lmo->r_version_offset,
+                        (unsigned char *) &r_version,
+                        sizeof (r_version)) != 0
+      || r_version != 1)
+    {
+      warning ("unexpected r_debug version %d", r_version);
+      return;
+    }
+
+  if (read_one_ptr (priv->r_debug + lmo->r_map_offset,
+                   &lm_addr, ptr_size) != 0)
+    {
+      warning ("unable to read r_map from 0x%lx",
+              (long) priv->r_debug + lmo->r_map_offset);
+      return;
+    }
+
+  clear_all_dlls ();
+
+  lm_prev = 0;
+  while (read_one_ptr (lm_addr + lmo->l_name_offset,
+                      &l_name, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_addr_offset,
+                         &l_addr, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_prev_offset,
+                         &l_prev, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_next_offset,
+                         &l_next, ptr_size) == 0)
+    {
+      unsigned char libname[PATH_MAX];
+
+      if (lm_prev != l_prev)
+       {
+         warning ("corrupt solib chain: 0x%lx != 0x%lx",
+                  (long) lm_prev, (long) l_prev);
+         break;
+       }
+
+      /* Not checking for error because reading may stop before
+        we've got PATH_MAX worth of characters.  */
+      libname[0] = '\0';
+      linux_read_memory (l_name, libname, sizeof (libname));
+      libname[sizeof (libname) - 1] = '\0';
+      if (libname[0] != '\0')
+       loaded_dll ((const char *) libname, l_addr);
+
+      if (l_next == 0)
+       break;
+
+      lm_prev = lm_addr;
+      lm_addr = l_next;
+    }
+
+  /* The library notification response is not expected for GNU/Linux.  */
+  dlls_changed = 0;
+}
+
+
 static struct target_ops linux_target_ops = {
   linux_create_inferior,
   linux_attach,

=== Part of the linux_refresh_libraries / clear_all_dlls patch. Not needed upstream.

@@ -5165,7 +5479,8 @@ static struct target_ops linux_target_op
   linux_cancel_breakpoints,
   linux_stabilize_threads,
   linux_install_fast_tracepoint_jump_pad,
-  linux_emit_ops
+  linux_emit_ops,
+  linux_refresh_libraries
 };
 
 static void

=== Part of the linux_refresh_libraries / clear_all_dlls patch. Not needed upstream.

diff -pruN gdb.git/gdb/gdbserver/server.c android/gdb.git/gdb-7.3.x/gdb/gdbserver/server.c
--- gdb.git/gdb/gdbserver/server.c      2012-03-27 12:26:23.163522817 -0300
+++ android/gdb.git/gdb-7.3.x/gdb/gdbserver/server.c    2012-02-22 21:59:49.684406194 -0200
@@ -1355,6 +1356,9 @@ handle_query (char *own_buf, int packet_
          gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
        }
 
+      if (the_target->refresh_libraries != NULL)
+       the_target->refresh_libraries ();
+
       sprintf (own_buf, "QC");
       own_buf += 2;
       write_ptid (own_buf, gdb_id);
diff -pruN gdb.git/gdb/gdbserver/server.h android/gdb.git/gdb-7.3.x/gdb/gdbserver/server.h

=== Part of the linux_refresh_libraries / clear_all_dlls patch. Not needed upstream.

--- gdb.git/gdb/gdbserver/server.h      2012-03-27 12:26:23.163522817 -0300
+++ android/gdb.git/gdb-7.3.x/gdb/gdbserver/server.h    2012-02-22 21:59:49.688406235 -0200
@@ -319,6 +319,7 @@ ptid_t thread_id_to_gdb_id (ptid_t);
 ptid_t thread_to_gdb_id (struct thread_info *);
 ptid_t gdb_id_to_thread_id (ptid_t);
 struct thread_info *gdb_id_to_thread (unsigned int);
+void clear_all_dlls (void);
 void clear_inferiors (void);
 struct inferior_list_entry *find_inferior
      (struct inferior_list *,

=== Part of the linux_refresh_libraries / clear_all_dlls patch. Not needed upstream.

diff -pruN gdb.git/gdb/gdbserver/target.h android/gdb.git/gdb-7.3.x/gdb/gdbserver/target.h
--- gdb.git/gdb/gdbserver/target.h      2012-03-27 12:26:23.163522817 -0300
+++ android/gdb.git/gdb-7.3.x/gdb/gdbserver/target.h    2012-02-22 21:59:49.688406235 -0200
@@ -373,6 +373,9 @@ struct target_ops
   /* Return the bytecode operations vector for the current inferior.
      Returns NULL if bytecode compilation is not supported.  */
   struct emit_ops *(*emit_ops) (void);
+
+  /* Refresh ALL_DLLS.  */
+  void (*refresh_libraries) (void);
 };
 
 extern struct target_ops *the_target;

=== Part of the linux_refresh_libraries / clear_all_dlls patch. Not needed upstream.

diff -pruN gdb.git/gdb/gdbserver/thread-db.c android/gdb.git/gdb-7.3.x/gdb/gdbserver/thread-db.c
--- gdb.git/gdb/gdbserver/thread-db.c   2012-03-27 12:26:23.163522817 -0300
+++ android/gdb.git/gdb-7.3.x/gdb/gdbserver/thread-db.c 2012-02-22 21:59:49.688406235 -0200
@@ -28,6 +28,13 @@ extern int debug_threads;
 static int thread_db_use_events;
 
 #include "gdb_proc_service.h"
+#define GDBSERVER /* GOOGLE LOCAL: see gdb_thread_db.h */
+
+/* Android doesn't have libthread_db.so.1, just libthread_db.so.  */
+#ifdef __ANDROID__
+#define LIBTHREAD_DB_SO "libthread_db.so"
+#endif
+
 #include "../gdb_thread_db.h"
 
 #ifndef USE_LIBTHREAD_DB_DIRECTLY
diff -pruN gdb.git/gdb/solib-svr4.c android/gdb.git/gdb-7.3.x/gdb/solib-svr4.c

=== Adapt to Android-specific libthread_db.so name. Need to upstream.

--- gdb.git/gdb/solib-svr4.c    2012-03-27 12:26:23.435525963 -0300
+++ android/gdb.git/gdb-7.3.x/gdb/solib-svr4.c  2012-02-22 21:59:49.924408605 -0200
@@ -106,6 +106,201 @@ static const  char * const main_name_lis
   NULL
 };
 
+
+static void
+svr4_free_so (struct so_list *so)
+{
+  xfree (so->lm_info->lm);
+  xfree (so->lm_info);
+}
+
+#if defined(HAVE_LIBEXPAT)
+
+#include "xml-support.h"
+
+/* Handle the start of a <segment> element.  */
+
+static void
+library_list_start_segment (struct gdb_xml_parser *parser,
+                           const struct gdb_xml_element *element,
+                           void *user_data, VEC(gdb_xml_value_s) *attributes)
+{
+  ULONGEST *address_p = xml_find_attribute (attributes, "address")->value;
+  CORE_ADDR address = (CORE_ADDR) *address_p;
+  struct so_list **so_list = user_data;
+
+  (*so_list)->lm_info->l_addr = address;
+}
+
+/* Handle the start of a <library> element.  Note: new elements are added
+   at the head of the list (i.e. the list is built in reverse order).  */
+
+static void
+library_list_start_library (struct gdb_xml_parser *parser,
+                           const struct gdb_xml_element *element,
+                           void *user_data, VEC(gdb_xml_value_s) *attributes)
+{
+  const char *name = xml_find_attribute (attributes, "name")->value;
+  struct so_list *new_elem, **so_list = user_data;
+
+  new_elem = XZALLOC (struct so_list);
+  new_elem->next = *so_list;
+  new_elem->lm_info = XZALLOC (struct lm_info);
+  strcpy (new_elem->so_original_name, name);
+  strcpy (new_elem->so_name, name);
+
+  *so_list = new_elem;
+}
+
+static void
+library_list_end_library (struct gdb_xml_parser *parser,
+                         const struct gdb_xml_element *element,
+                         void *user_data, const char *body_text)
+{
+  struct so_list **so_list = user_data;
+
+  if ((*so_list)->lm_info->l_addr == 0)
+    gdb_xml_error (parser, _("No segment defined for %s"),
+                  (*so_list)->so_name);
+}
+
+
+/* Handle the start of a <library-list> element.  */
+
+static void
+library_list_start_list (struct gdb_xml_parser *parser,
+                        const struct gdb_xml_element *element,
+                        void *user_data, VEC(gdb_xml_value_s) *attributes)
+{
+  char *version = xml_find_attribute (attributes, "version")->value;
+
+  if (strcmp (version, "1.0") != 0)
+    gdb_xml_error (parser,
+                  _("Library list has unsupported version \"%s\""),
+                  version);
+}
+
+
+/* The allowed elements and attributes for an XML library list.
+   The root element is a <library-list>.  */
+
+static const struct gdb_xml_attribute segment_attributes[] = {
+  { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element library_children[] = {
+  { "segment", segment_attributes, NULL,
+    GDB_XML_EF_NONE, library_list_start_segment, NULL },
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute library_attributes[] = {
+  { "name", GDB_XML_AF_NONE, NULL, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element library_list_children[] = {
+  { "library", library_attributes, library_children,
+    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
+    library_list_start_library, library_list_end_library },
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute library_list_attributes[] = {
+  { "version", GDB_XML_AF_NONE, NULL, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element library_list_elements[] = {
+  { "library-list", library_list_attributes, library_list_children,
+    GDB_XML_EF_NONE, library_list_start_list, NULL },
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+/* Free so_list built so far (called via cleanup).  */
+
+static void
+svr4_free_library_list (void *p_list)
+{
+  struct so_list *list = *(struct so_list **) p_list;
+  while (list != NULL)
+    {
+      struct so_list *next = list->next;
+
+      svr4_free_so (list);
+      list = next;
+    }
+}
+
+/* Parse qXfer:libraries:read packet into so_list.  */
+
+static struct so_list *
+svr4_parse_libraries (const char *document)
+{
+  struct so_list *result = NULL;
+  struct cleanup *back_to = make_cleanup (svr4_free_library_list,
+                                         &result);
+
+  if (gdb_xml_parse_quick (_("target library list"), "library-list.dtd",
+                          library_list_elements, document, &result) == 0)
+    {
+      struct so_list *prev;
+
+      /* Parsed successfully, keep the result.  */
+      discard_cleanups (back_to);
+
+      /* Reverse the list -- it was built in reverse order.  */
+      prev = NULL;
+      while (result)
+       {
+         struct so_list *next = result->next;
+
+         result->next = prev;
+         prev = result;
+         result = next;
+       }
+      return prev;
+    }
+
+  do_cleanups (back_to);
+  return NULL;
+}
+
+/* Attempt to get so_list from target via qXfer:libraries:read packet.
+   Return NULL if packet not supported, or contains no libraries.  */
+
+static struct so_list *
+svr4_current_sos_via_xfer_libraries ()
+{
+  char *library_document;
+  struct so_list *result;
+  struct cleanup *back_to;
+
+  /* Fetch the list of shared libraries.  */
+  library_document = target_read_stralloc (&current_target,
+                                          TARGET_OBJECT_LIBRARIES,
+                                          NULL);
+  if (library_document == NULL)
+    return NULL;
+
+  back_to = make_cleanup (xfree, library_document);
+  result = svr4_parse_libraries (library_document);
+  do_cleanups (back_to);
+
+  return result;
+}
+
+#else
+
+static struct so_list *
+svr4_current_sos_via_xfer_libraries ()
+{
+  return NULL;
+}
+
+#endif
+
 /* Return non-zero if GDB_SO_NAME and INFERIOR_SO_NAME represent
    the same shared library.  */
 

=== Part of the linux_refresh_libraries / clear_all_dlls patch. Not needed upstream.

@@ -1114,6 +1309,10 @@ svr4_current_sos (void)
   CORE_ADDR ldsomap = 0;
   struct svr4_info *info;
 
+  head = svr4_current_sos_via_xfer_libraries ();
+  if (head != NULL)
+    return head;
+
   info = get_svr4_info ();
 
   /* Always locate the debug struct, in case it has moved.  */

=== Part of the linux_refresh_libraries / clear_all_dlls patch. Not needed upstream.

@@ -2227,13 +2426,6 @@ svr4_clear_solib (void)
   info->debug_loader_name = NULL;
 }
 
-static void
-svr4_free_so (struct so_list *so)
-{
-  xfree (so->lm_info->lm);
-  xfree (so->lm_info);
-}
-
 
 /* Clear any bits of ADDR that wouldn't fit in a target-format
    data pointer.  "Data pointer" here refers to whatever sort of

=== Part of the linux_refresh_libraries / clear_all_dlls patch. Not needed upstream.

diff -pruN gdb.git/gdb/top.c android/gdb.git/gdb-7.3.x/gdb/top.c
--- gdb.git/gdb/top.c   2012-03-27 12:26:24.371536800 -0300
+++ android/gdb.git/gdb-7.3.x/gdb/top.c 2012-02-22 21:59:51.056419973 -0200
@@ -1301,6 +1309,17 @@ input_from_terminal_p (void)
 
   return 0;
 }
+
+/* This function is *here* because it is used in breakpoint.c  */
+
+int
+is_target_linux_android ()
+{
+  if (strstr (target_name, "android") != NULL
+      && strstr (target_name, "linux") != NULL)
+    return 1;
+  return 0;
+}
 
 static void
 dont_repeat_command (char *ignored, int from_tty)


=== Part of the longjmp buffer support. Submitted upstream.

ThiagoBauermann/Sandbox/AOSPPatches (last modified 2012-06-22 21:39:24)