--- /dev/null	2024-11-04 03:30:07.620098835 -0600
+++ ./gdb/mmapfile.c	2024-11-04 03:25:40.999273919 -0600
@@ -0,0 +1,329 @@
+/* This implememts the mmapfile command for gdb */
+ #include "defs.h"
+ #include "infcall.h"
+ #include "inferior.h"
+ #include "gdbcore.h"
+ #include "objfiles.h"
+ #include "solib.h"
+ #include "symfile.h"
+ #include "arch-utils.h"
+ #include "completer.h"
+ #include "cli/cli-decode.h"
+ #include <fcntl.h>
+ #include "regcache.h"
+ #include "regset.h"
+ #include "sys/mman.h"
+ #include "filenames.h"
+ #include "readline/tilde.h"
+ #include "gdbsupport/pathstuff.h"
+ #include "source.h"
+ #include "gdbsupport/filestuff.h"
+
+ #define core_bfd (current_program_space->cbfd.get ())
+ 
+ int count = 1;
+ typedef int mmap_openp_flags;
+ int mmap_fileopen(const char*, mmap_openp_flags, const char*, int, gdb::unique_xmalloc_ptr<char>*);
+ 
+ int
+ mmap_fileopen (const char *path, mmap_openp_flags opts, const char *string,
+        int mode, gdb::unique_xmalloc_ptr<char> *filename_opened)
+ {
+   int fd; 
+   char *filename;
+   int alloclen;
+   /* The errno set for the last name we tried to open (and
+      failed).  */
+   int last_errno = 0;
+   std::vector<gdb::unique_xmalloc_ptr<char>> dir_vec;
+ 
+   /* The open syscall MODE parameter is not specified.  */
+   gdb_assert ((mode & O_CREAT) == 0);
+   gdb_assert (string != NULL);
+
+   /* A file with an empty name cannot possibly exist.  Report a failure 
+      without further checking.
+ 
+      This is an optimization which also defends us against buggy
+      implementations of the "stat" function.  For instance, we have
+      noticed that a MinGW debugger built on Windows XP 32bits crashes
+      when the debugger is started with an empty argument.  */
+   if (string[0] == '\0')
+     {
+       errno = ENOENT;
+       return -1;
+     }
+ 
+   if (!path)
+     path = ".";
+ 
+   if ((opts & 0x01) || IS_ABSOLUTE_PATH (string)) //OPF_TRY_CWD_FIRST     0x01
+     {
+       int i;
+ 
+        filename = (char *) alloca (strlen (string) +  1);
+        strcpy (filename, string);
+        fd = open (filename, O_RDONLY);
+        if (fd >= 0)
+           goto done;
+        last_errno = errno;
+ 
+       if (!(opts & 0x02))//OPF_SEARCH_IN_PATH 
+         for (i = 0; string[i]; i++)
+           if (IS_DIR_SEPARATOR (string[i]))
+             goto done;
+     }
+ 
+   /* For dos paths, d:/foo -> /foo, and d:foo -> foo.  */
+   if (HAS_DRIVE_SPEC (string))
+     string = STRIP_DRIVE_SPEC (string);
+ 
+   /* /foo => foo, to avoid multiple slashes that Emacs doesn't like.  */
+   while (IS_DIR_SEPARATOR(string[0]))
+     string++;
+ 
+   /* ./foo => foo */
+   while (string[0] == '.' && IS_DIR_SEPARATOR (string[1]))
+     string  += 2;
+ 
+   alloclen = strlen (path) +  strlen (string) +  2;
+   filename = (char *) alloca (alloclen);
+   fd = -1;
+   last_errno = ENOENT;
+   dir_vec  = dirnames_to_char_ptr_vec (path);
+ 
+   for (const gdb::unique_xmalloc_ptr<char> &this_dir_up : dir_vec)
+     {
+       const char *this_dir = this_dir_up.get ();
+       size_t len = strlen (this_dir);
+       int reg_file_errno;
+ 
+       if (strcmp (this_dir, "$cwd") == 0)
+         {
+           /* Name is $cwd -- insert current directory name instead.  */
+           int newlen;
+ 
+           /* First, realloc the filename buffer if too short.  */
+           len = strlen (current_directory);
+           newlen = len +  strlen (string) +  2;
+           if (newlen > alloclen)
+             {
+               alloclen = newlen;
+               filename = (char *) alloca (alloclen);
+             }
+           strcpy (filename, current_directory);
+         }
+       else if (strchr(this_dir, '~'))
+         {
+          /* See whether we need to expand the tilde.  */
+           int newlen;
+ 
+           gdb::unique_xmalloc_ptr<char> tilde_expanded (tilde_expand (this_dir));
+ 
+           /* First, realloc the filename buffer if too short.  */
+           len = strlen (tilde_expanded.get ());
+           newlen = len +  strlen (string) +  2;
+           if (newlen > alloclen)
+             {
+               alloclen = newlen;
+               filename = (char *) alloca (alloclen);
+             }
+           strcpy (filename, tilde_expanded.get ());
+         }
+       else
+         {
+           /* Normal file name in path -- just use it.  */
+           strcpy (filename, this_dir);
+ 
+           /* Don't search $cdir.  It's also a magic path like $cwd, but we
+              don't have enough information to expand it.  The user *could*
+              have an actual directory named '$cdir' but handling that would
+              be confusing, it would mean different things in different
+              contexts.  If the user really has '$cdir' one can use './$cdir'.
+              We can get $cdir when loading scripts.  When loading source files
+              $cdir must have already been expanded to the correct value.  */
+           if (strcmp (this_dir, "$cdir") == 0)
+             continue;
+         }
+ 
+       /* Remove trailing slashes.  */
+       while (len > 0 && IS_DIR_SEPARATOR (filename[len - 1]))
+         filename[--len] = 0;
+ 
+       strcat (filename +  len, SLASH_STRING);
+       strcat (filename, string);
+ 
+       if (is_regular_file (filename, &reg_file_errno))
+         {
+           fd = open (filename, O_RDONLY);
+           if (fd >= 0)
+             break;
+           last_errno = errno;
+         }
+       else
+         last_errno = reg_file_errno;
+     }
+ 
+ done:
+   if (filename_opened)
+     {
+       /* If a file was opened, canonicalize its filename.  */
+       gdb::unique_xmalloc_ptr<char> mmap_filename_opened;
+       if (fd < 0)
+         *filename_opened = NULL;
+       else if ((opts & 0x04) != 0) //OPF_RETURN_REALPATH   0x04
+         *filename_opened = gdb_realpath (filename); 
+       else
+         *filename_opened = gdb_realpath (filename); 
+     }
+ 
+   errno = last_errno;
+   return fd;
+ }
+ 
+ static void
+ mmap_command (const char *args, int from_tty)
+ {
+        openp_flag TRY_CWD = OPF_TRY_CWD_FIRST;
+	openp_flag RETURN_REALPATH = OPF_RETURN_REALPATH; 
+        CORE_ADDR       			addr;
+         std::vector<target_section> mmap_data;
+         asection                *sec, *vmsec;
+         int                     fd, flags;
+         char                    *mmapsec_name, *sec_name;
+ 	gdb::unique_xmalloc_ptr<char> file_pathname;
+ 
+         off64_t offset  = 0;
+         caddr_t vaddr   = NULL;
+         size_t size     = 0;
+         int i = 0;
+         char *arg[4];
+ 
+ 
+         arg[i] = strtok (args," ");
+ 
+         while (arg[i++] != NULL)
+                 arg[i] = strtok (NULL, " ");
+ 
+ /* Check if the parameters entered by the user are correct in number and format */
+ 
+         if (i != 5)
+                 error (_("MMAP ERROR: Usage: mmapfile <FILENAME> <MAP-ADDRESS> \
+ <FILE-OFFSET> <LENGTH>"));
+ 
+ /* No point using mmap if gdb is not debugging a core */
+ 
+         if (core_bfd == NULL)
+                 error (_("MMAP ERROR: No core file loaded."));
+ 
+ /* Find out if the user entered offset and size in base 16 or base 10 */
+ 
+         if (arg[2][0] == '0' && arg[2][1] == 'x')
+                 offset  = strtoll(arg[2], NULL, 16);
+         else
+                 offset  = strtoll(arg[2], NULL, 10);
+ 
+         if (arg[3][0] == '0' && arg[3][1] == 'x')
+                 size    = strtoll(arg[3], NULL, 16);
+         else
+                 size    = strtoll(arg[3], NULL, 10);
+ 
+         addr = parse_and_eval_address (arg[1]);
+ 
+ /* Check if the desired mmap address overlaps with an already existing
+    virtual memory address in the core. If so, then display error */
+ 
+         vmsec   = bfd_get_section_by_name(core_bfd, ".vmdata");
+ 
+         gdb::unique_xmalloc_ptr<char> expanded_name (tilde_expand (arg[0]));
+ 
+         while (vmsec != NULL)
+         {
+                 if (addr >= vmsec->vma && addr < (vmsec->vma +  vmsec->size))
+ 
+                         error(_("MMAP_ERROR:\nCannot memory map file <%s> at\n\
+ address 0x%15.lX as it results in an overlap\nuse info target for more info"), arg[0], addr);
+ 
+ 
+                 if (strcmp (vmsec->next->name, ".vmdata") == 0)
+                         vmsec = vmsec->next;
+                 else
+                         vmsec = NULL;
+         }
+ 
+         if (size == 0)
+                 error (_("MMAP ERROR: size cannot be 0"));
+ 
+ /* Get file descriptor for the desired file to be mmaped */
+ 
+         fd = mmap_fileopen (getenv("PATH"),
+                             TRY_CWD | RETURN_REALPATH,
+                             expanded_name.get (),
+ 		            O_RDONLY,	
+                             &file_pathname);
+         if (fd < 0)
+                 perror_with_name (arg[0]);
+ 
+         flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+ 
+ /* mmap the given file to the desired address/symbol and let vaddr point to it */
+ 
+         vaddr = (char *)mmap((void *)addr, size, PROT_READ, MAP_FIXED | MAP_SHARED, fd, offset);
+ 
+         if ((long) vaddr == -1)
+                    error(_("MMAP_ERROR:\nCannot memory map file <%s> at\n\
+ address 0x%15.lX as it results in an overlap\nuse info target for more info"), arg[0], addr);
+ 
+ /* Get a unique section name and assign it to the new section created in the core */
+ 
+         mmapsec_name = bfd_get_unique_section_name (core_bfd, "mmap_section", &count);
+ 
+         sec_name = (unsigned char *)malloc (snprintf (NULL, 0, "%s (Mapped to %s)", mmapsec_name, file_pathname.get()));
+ 
+         sprintf(sec_name, "%s (Mapped to %s)", mmapsec_name, file_pathname.get());
+ 
+ /* Create a new section in the core_bfd with this unique section name */
+ 
+         sec = bfd_make_section_anyway_with_flags (core_bfd, sec_name, flags);
+ 
+ /* Fill out the required section contents */
+ 
+         sec->contents = (unsigned char*) vaddr;
+         bfd_set_section_vma (sec, (unsigned long int)vaddr);
+         bfd_set_section_alignment (sec, 0);
+         bfd_set_section_size (sec, size);
+ 
+ /* Build a new section table which has contains all the sections present
+    in core_bfd and also the newly created mmap section */
+ 
+         //mmap_data = new target_section_table;
+ 
+         mmap_data = build_section_table   (current_program_space->cbfd.get ());
+ 
+         close(fd);
+         mmap_core (mmap_data);
+         gdb_printf (_("File %s is now mapped\nfrom address %lX to %lX.\n"), file_pathname.get(), addr, addr+ size);
+ }
+ 
+ /* Implement mmap command and add it to the commands list */
+ 
+ extern initialize_file_ftype _initialize_mmap;
+ 
+void
+_initialize_mmap (void)
+{
+   const char *add_cmd = "mmapfile";
+   struct cmd_list_element *c = add_com(add_cmd, class_vars, mmap_command, _("\
+Add contents of memory mapped files missing from core dump.\n\n\
+Usage:\nmmapfile <FILENAME> <MAP-ADDRESS / SYMBOL NAME> <FILE-OFFSET> <LENGTH>\n\
+Command is used (mostly while debugging a core) if the core file sections do not contain\n\
+memory mapped regions under the vmdata section.\n\
+This happens if files are mmap-ed with MMAP_PRIVATE/MAP_SHARED and RO permissions.\n\
+Using this command, the user can access data from\n\
+the mmap-ed files, which are missing from the core file."));
+
+set_cmd_completer (c, NULL);
+add_com_alias ("mmap", c, class_files, 1);
+}
+
+
--- ./gdb/gdbcore.h_orig	2024-11-04 03:02:25.504563690 -0600
+++ ./gdb/gdbcore.h	2024-11-04 03:13:26.336153986 -0600
@@ -29,6 +29,10 @@
 #include "exec.h"
 #include "target.h"
 
+/* Get the updated core_data after mmap */
+
+extern void mmap_core (std::vector<target_section> coreinfo_data);
+
 /* Nonzero if there is a core file.  */
 
 extern int have_core_file_p (void);
--- ./gdb/corelow.c_orig	2024-11-04 03:03:23.460896645 -0600
+++ ./gdb/corelow.c	2024-11-04 03:15:22.974379316 -0600
@@ -87,6 +87,8 @@
 					ULONGEST *xfered_len) override;
   void files_info () override;
 
+  void set_core_data_aix (std::vector<target_section> core_data);
+
   bool thread_alive (ptid_t ptid) override;
   const struct target_desc *read_description () override;
 
@@ -171,6 +173,13 @@
   struct gdbarch *m_core_gdbarch = NULL;
 };
 
+void
+core_target::set_core_data_aix(std::vector<target_section> core_data)
+{
+      m_core_section_table = core_data;
+}
+
+
 core_target::core_target ()
 {
   /* Find a first arch based on the BFD.  We need the initial gdbarch so
@@ -1448,6 +1457,16 @@
   return dynamic_cast<core_target *> (proc_target);
 }
 
+/* mmap core command */
+void
+mmap_core (std::vector<target_section> coreinfo_data)
+{  
+  core_target *targ = get_current_core_target (); 
+  if (targ != nullptr)
+    targ->set_core_data_aix (coreinfo_data); 
+}
+
+
 /* Display file backed mappings from core file.  */
 
 void
--- ./gdb/Makefile.in_orig	2024-11-04 03:07:13.023331737 -0600
+++ ./gdb/Makefile.in	2024-11-04 03:07:34.629992491 -0600
@@ -1165,6 +1165,7 @@
 	memattr.c \
 	memory-map.c \
 	memrange.c \
+        mmapfile.c \
 	memtag.c \
 	minidebug.c \
 	minsyms.c \
