--- ./gdb/rs6000-tdep.h_orig	2018-08-26 12:58:08 +0000
+++ ./gdb/rs6000-tdep.h	2018-08-26 12:57:45 +0000
@@ -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	2018-08-26 12:58:45 +0000
+++ ./gdb/rs6000-tdep.c	2018-08-26 13:04:19 +0000
@@ -61,6 +61,8 @@
 #include "trad-frame.h"
 #include "frame-unwind.h"
 #include "frame-base.h"
+#include "rs6000-tdep.h"
+#include "xcoffread.h"
 
 #include "ax.h"
 #include "ax-gdb.h"
@@ -3273,7 +3275,7 @@
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct rs6000_framedata fdata;
   int wordsize = tdep->wordsize;
-  CORE_ADDR func = 0, pc = 0;
+  CORE_ADDR func = 0, pc = 0, save_cache_base;
 
   if ((*this_cache) != NULL)
     return (struct rs6000_frame_cache *) (*this_cache);
@@ -3298,6 +3300,7 @@
 	 base address of this frame.  */
       cache->base = get_frame_register_unsigned
 	(this_frame, gdbarch_sp_regnum (gdbarch));
+      save_cache_base = cache->base;
     }
   CATCH (ex, RETURN_MASK_ERROR)
     {
@@ -3347,6 +3350,39 @@
 					     byte_order, &backchain))
         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	2018-08-26 13:09:30 +0000
+++ ./gdb/xcoffread.h	2018-08-26 12:57:45 +0000
@@ -23,4 +23,6 @@
 
 extern int xcoff_get_n_import_files (bfd *abfd);
 
+extern int is64;
+
 #endif /* xcoffread.h */
--- ./gdb/xcoffread.c_orig	2018-08-26 13:05:15 +0000
+++ ./gdb/xcoffread.c	2018-08-26 12:57:45 +0000
@@ -49,6 +49,8 @@
 
 #include "gdb-stabs.h"
 
+int is64;
+
 /* For interface with stabsread.c.  */
 #include "aout/stab_gnu.h"
 
@@ -1747,6 +1749,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	2018-08-26 13:06:21 +0000
+++ ./gdb/frame.c	2018-08-26 12:57:45 +0000
@@ -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;
 
 /* The sentinel frame terminates the innermost end of the frame chain.
    If unwound, it returns the information needed to construct an
@@ -787,7 +791,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=");
@@ -1282,6 +1295,7 @@
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
   struct value *value = frame_unwind_register_value (frame, regnum);
+  ULONGEST base_addr;
 
   gdb_assert (value != NULL);
 
@@ -1298,7 +1312,38 @@
 
   ULONGEST r = extract_unsigned_integer (value_contents_all (value), 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 (r && (r < AIX_TEXT_SEGMENT_BASE)) {
+      aix_sig_millicode = r;
+      if (is64)  {
+        if (frame_id_p(get_frame_id (frame)) == 0) {
+              base_addr =  get_frame_register_unsigned (frame, gdbarch_sp_regnum (gdbarch)); 
+              r = read_memory_unsigned_integer
+                 (base_addr + SIG_FRAME_PC_OFFSET64,
+                 size, byte_order);
+          } else {
+              r = 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)); 
+              r = read_memory_unsigned_integer
+                (base_addr + SIG_FRAME_PC_OFFSET+8,
+                size, byte_order);
+        } else {
+            r = read_memory_unsigned_integer
+                 (get_frame_base (frame) + SIG_FRAME_PC_OFFSET+8,
+                size, byte_order);
+        }
+      }
+  }
   release_value (value);
   value_free (value);
   return r;
