--- ./gdb/rs6000-tdep.h_orig	2016-06-21 02:06:27.000000000 -0500
+++ ./gdb/rs6000-tdep.h	2016-06-21 04:57:24.000000000 -0500
@@ -18,3 +18,21 @@
 /* Minimum possible text address in AIX.  */
 #define AIX_TEXT_SEGMENT_BASE 0x10000000
 
+/* For sighandler */
+
+/* STKMIN(minimum stack size) is 56 for 32-bit process
+   and iar offset under sc_jmpbuf.jmp_context is 40 under the sigconext structure.
+   ie offsetof(struct sigcontext, sc_jmpbuf.jmp_context.iar).
+   so PC offset in this case is STKIM+iar offset, which is 96 */
+#define SIG_FRAME_PC_OFFSET 96
+#define SIG_FRAME_LR_OFFSET 108
+/* STKMIN+grp1 offset, which is 56+228=284 */
+#define SIG_FRAME_FP_OFFSET 284
+
+/* 64 bit process */
+/* STKMIN64  is 112 and iar offset is 312. So 112+312=424 */
+#define SIG_FRAME_PC_OFFSET64 424
+/* STKMIN64+grp1 offset. 112+56=168 */
+#define SIG_FRAME_FP_OFFSET64 168 
+
+#define EXT_CONTEXT64 452
--- ./gdb/rs6000-tdep.c_orig	2016-06-21 02:05:28.000000000 -0500
+++ ./gdb/rs6000-tdep.c	2016-06-21 04:56:56.000000000 -0500
@@ -62,6 +62,8 @@
 #include "trad-frame.h"
 #include "frame-unwind.h"
 #include "frame-base.h"
+#include "rs6000-tdep.h"
+#include "xcoffread.h"
 
 #include "features/rs6000/powerpc-32.c"
 #include "features/rs6000/powerpc-altivec32.c"
@@ -3145,7 +3147,7 @@
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct rs6000_framedata fdata;
   int wordsize = tdep->wordsize;
-  CORE_ADDR func, pc;
+  CORE_ADDR func, pc, save_cache_base;
 
   if ((*this_cache) != NULL)
     return (*this_cache);
@@ -3166,6 +3168,7 @@
      base address of this frame.  */
   cache->base = get_frame_register_unsigned
 		(this_frame, gdbarch_sp_regnum (gdbarch));
+  save_cache_base = cache->base;
 
   /* If the function appears to be frameless, check a couple of likely
      indicators that we have simply failed to find the frame setup.
@@ -3208,6 +3211,41 @@
         cache->base = (CORE_ADDR) backchain;
     }
 
+  /* If frame is a AIX signal handler frame, we need to read the base 
+     address from sigconext offset. Backchain at an offset 0 will be 0, so backchain
+     will be at an offset SIG_FRAME_FP_OFFSET(284)+8 for 32-bit applications. */
+  if (!cache->base && !fdata.frameless)
+  {
+      CORE_ADDR backchain, sig_pc = 0, msr = 0, msr_chain;
+      
+       if (is64) {
+         if (safe_read_memory_integer (save_cache_base+16, wordsize, byte_order, &sig_pc) &&
+            (sig_pc && (sig_pc < AIX_TEXT_SEGMENT_BASE))) {
+              /* Check if we have VMS/VXS extended context saved */
+              if (safe_read_memory_integer (save_cache_base+EXT_CONTEXT64, 4, byte_order, &msr) &&
+                  (msr == 0x20000000)) {
+                   if (safe_read_memory_integer (save_cache_base+SIG_FRAME_FP_OFFSET64,
+                                                 wordsize, byte_order, &msr_chain))
+                       if (safe_read_memory_integer (msr_chain, wordsize, byte_order, &backchain))
+                           cache->base = (CORE_ADDR) backchain;
+              } else { 
+                  /* printf("In read stack sig previous\n"); */ 
+                  if (safe_read_memory_integer (save_cache_base+SIG_FRAME_FP_OFFSET64, 
+                                                wordsize, byte_order, &backchain))
+                      cache->base = (CORE_ADDR) backchain;
+                   /* printf("In read stack sig previous %lu\n", backchain); */
+              }
+         }
+      } else {
+          if (safe_read_memory_integer (save_cache_base+8, wordsize, byte_order, &sig_pc) && 
+            (sig_pc && (sig_pc < AIX_TEXT_SEGMENT_BASE)))
+              if (safe_read_memory_integer (save_cache_base+SIG_FRAME_FP_OFFSET+8,
+                                             wordsize, byte_order, &backchain))
+                  cache->base = (CORE_ADDR) backchain;
+      }
+  }
+  
+  
   trad_frame_set_value (cache->saved_regs,
 			gdbarch_sp_regnum (gdbarch), cache->base);
 
--- ./gdb/xcoffread.h_orig	2016-06-21 05:09:30.000000000 -0500
+++ ./gdb/xcoffread.h	2016-06-21 05:10:35.000000000 -0500
@@ -23,4 +23,6 @@
 
 extern int xcoff_get_n_import_files (bfd *abfd);
 
+extern int is64;
+
 #endif /* xcoffread.h */
--- ./gdb/xcoffread.c_orig	2016-06-22 00:31:25.000000000 -0500
+++ ./gdb/xcoffread.c	2016-06-22 00:31:59.000000000 -0500
@@ -49,6 +49,8 @@
 
 #include "gdb-stabs.h"
 
+int is64;
+
 /* For interface with stabsread.c.  */
 #include "aout/stab_gnu.h"
 
@@ -1729,6 +1731,7 @@
 {
   struct objfile *objfile = this_symtab_objfile;
   int xcoff64 = bfd_xcoff_is_xcoff64 (objfile->obfd);
+  is64 = xcoff64;
 
   struct coff_symfile_info *info = XCOFF_DATA (objfile);
   int nsyms = info->symtbl_num_syms;
--- ./gdb/frame.c_orig	2017-05-03 09:20:31 -0500
+++ ./gdb/frame.c	2017-05-03 08:58:40 -0500
@@ -42,6 +42,10 @@
 #include "tracepoint.h"
 #include "hashtab.h"
 #include "valprint.h"
+#include "rs6000-tdep.h"
+#include "xcoffread.h"
+
+CORE_ADDR aix_sig_millicode;
 
 static struct frame_info *get_prev_frame_raw (struct frame_info *this_frame);
 static const char *frame_stop_reason_symbol_string (enum unwind_stop_reason reason);
@@ -717,7 +721,16 @@
        comment in "frame.h", there is some fuzz here.  Frameless
        functions are not strictly inner than (same .stack but
        different .code and/or .special address).  */
-    inner = gdbarch_inner_than (gdbarch, l.stack_addr, r.stack_addr);
+
+     /* For xlc generated address and signal handler case, their can be cases where
+        stack address of l frame is less than r frame. 
+        We may need to skip those cases for checking inner than. */ 
+       if (aix_sig_millicode && (aix_sig_millicode < AIX_TEXT_SEGMENT_BASE)) {
+           inner = 0;
+           aix_sig_millicode = 0;
+       }
+       else
+           inner = gdbarch_inner_than (gdbarch, l.stack_addr, r.stack_addr);
   if (frame_debug)
     {
       fprintf_unfiltered (gdb_stdlog, "{ frame_id_inner (l=");
@@ -1182,9 +1195,43 @@
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
   gdb_byte buf[MAX_REGISTER_SIZE];
+  CORE_ADDR pc, base_addr;
 
   frame_unwind_register (frame, regnum, buf);
-  return extract_unsigned_integer (buf, size, byte_order);
+  pc = extract_unsigned_integer (buf, size, byte_order);
+  /* Like to save the orignal pc value when handler is being called in AIX
+     When signal handler is being called pc value is actually the millicode address. */
+  /* if pc is something like 0x46dc, 0x4a5c etc..
+  Then it is most likekly the aix signal handler frame.
+  Read the pc from the signal handler frame at an offset 96+lr_offset. */
+  if (pc && (pc < AIX_TEXT_SEGMENT_BASE)) {
+      aix_sig_millicode = pc;
+      if (is64)  {
+	  if (frame_id_p(get_frame_id (frame)) == 0) {
+              base_addr =  get_frame_register_unsigned (frame, gdbarch_sp_regnum (gdbarch)); 
+              pc = read_memory_unsigned_integer
+                 (base_addr + SIG_FRAME_PC_OFFSET64,
+                 size, byte_order);
+          } else {
+		pc = read_memory_unsigned_integer
+                     (get_frame_base (frame) + SIG_FRAME_PC_OFFSET64,
+                      size, byte_order);
+          }
+      }
+      else {
+         if (frame_id_p(get_frame_id (frame)) == 0) {
+             base_addr =  get_frame_register_unsigned (frame, gdbarch_sp_regnum (gdbarch)); 
+             pc = read_memory_unsigned_integer
+                (base_addr + SIG_FRAME_PC_OFFSET+8,
+                size, byte_order);
+        } else {
+            pc = read_memory_unsigned_integer
+                 (get_frame_base (frame) + SIG_FRAME_PC_OFFSET+8,
+                size, byte_order);
+        }
+      }
+  }
+  return pc;
 }
 
 ULONGEST
