This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] procfs.c: iterating over memory regions.


Michael Snyder wrote:
> 
> There are two functions now that iterate over memory regions,
> and I'm about to add a third.  This patch implements a single
> general-purpose iterator over memory regions using callbacks,
> and reimplements the existing functions (shared libraries and
> info proc mappings) in terms of the new iterator.

Committed.
> 
> 2001-12-28  Michael Snyder  <msnyder@redhat.com>
> 
>         Abstract the functionality of iterating over mapped memory
>         regions into a general purpose iterator function.
>         procfs.c (iterate_over_mappings): New function, general purpose
>         iterator for memory sections.
>         (proc_iterate_over_mappings): Reimplement using iterate_over_mappings.
>         (solib_mappings_callback): New function, callback for above.
>         (info_proc_mappings): Reimpliment using iterate_over_mappings.
>         (info_mappings_callback): New function, callback for above.
> 
>         * procfs.c (proc_set_watchpoint): Add cast to suppress warning.
> 
> Index: procfs.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/procfs.c,v
> retrieving revision 1.33
> diff -c -3 -p -r1.33 procfs.c
> *** procfs.c    2001/12/28 19:47:08     1.33
> --- procfs.c    2001/12/28 20:59:42
> *************** proc_set_watchpoint (procinfo *pi, CORE_
> *** 2848,2854 ****
>     prwatch_t *pwatch;
> 
>     pwatch            = (prwatch_t *) &arg.watch;
> !   pwatch->pr_vaddr  = address_to_host_pointer (addr);
>     pwatch->pr_size   = len;
>     pwatch->pr_wflags = wflags;
>   #if defined(NEW_PROC_API) && defined (PCWATCH)
> --- 2848,2858 ----
>     prwatch_t *pwatch;
> 
>     pwatch            = (prwatch_t *) &arg.watch;
> ! #ifdef PCAGENT        /* Horrible hack: only defined on Solaris 2.6+ */
> !   pwatch->pr_vaddr  = (uintptr_t) address_to_host_pointer (addr);
> ! #else
> !   pwatch->pr_vaddr  = (caddr_t) address_to_host_pointer (addr);
> ! #endif
>     pwatch->pr_size   = len;
>     pwatch->pr_wflags = wflags;
>   #if defined(NEW_PROC_API) && defined (PCWATCH)
> *************** proc_set_watchpoint (procinfo *pi, CORE_
> *** 2865,2979 ****
>   #endif
>   }
> 
> - /*
> -  * Function: proc_iterate_over_mappings
> -  *
> -  * Given a pointer to a function, call that function once for every
> -  * mapped address space in the process.  The callback function
> -  * receives an open file descriptor for the file corresponding to
> -  * that mapped address space (if there is one), and the base address
> -  * of the mapped space.  Quit when the callback function returns a
> -  * nonzero value, or at teh end of the mappings.
> -  *
> -  * Returns: the first non-zero return value of the callback function,
> -  * or zero.
> -  */
> -
> - int
> - proc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
> - {
> -   struct prmap *map;
> -   procinfo *pi;
> - #ifndef NEW_PROC_API  /* avoid compiler warning */
> -   int nmaps = 0;
> -   int i;
> - #else
> -   int map_fd;
> -   char pathname[MAX_PROC_NAME_SIZE];
> - #endif
> -   int funcstat = 0;
> -   int fd;
> -
> -   pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
> -
> - #ifdef NEW_PROC_API
> -   /* Open map fd.  */
> -   sprintf (pathname, "/proc/%d/map", pi->pid);
> -   if ((map_fd = open_with_retry (pathname, O_RDONLY)) < 0)
> -     proc_error (pi, "proc_iterate_over_mappings (open)", __LINE__);
> -
> -   /* Make sure it gets closed again.  */
> -   make_cleanup_close (map_fd);
> -
> -   /* Allocate space for mapping (lifetime only for this function). */
> -   map = alloca (sizeof (struct prmap));
> -
> -   /* Now read the mappings from the file,
> -      open a file descriptor for those that have a name,
> -      and call the callback function.  */
> -   while (read (map_fd,
> -              (void *) map,
> -              sizeof (struct prmap)) == sizeof (struct prmap))
> -     {
> -       char name[MAX_PROC_NAME_SIZE + sizeof (map->pr_mapname)];
> -
> -       if (map->pr_vaddr == 0 && map->pr_size == 0)
> -       break;          /* sanity */
> -
> -       if (map->pr_mapname[0] == 0)
> -       {
> -         fd = -1;      /* no map file */
> -       }
> -       else
> -       {
> -         sprintf (name, "/proc/%d/object/%s", pi->pid, map->pr_mapname);
> -         /* Note: caller's responsibility to close this fd!  */
> -         fd = open_with_retry (name, O_RDONLY);
> -         /* Note: we don't test the above call for failure;
> -            we just pass the FD on as given.  Sometimes there is
> -            no file, so the ioctl may return failure, but that's
> -            not a problem.  */
> -       }
> -
> -       /* Stop looping if the callback returns non-zero.  */
> -       if ((funcstat = (*func) (fd, (CORE_ADDR) map->pr_vaddr)) != 0)
> -       break;
> -     }
> - #else
> -   /* Get the number of mapping entries.  */
> -   if (ioctl (pi->ctl_fd, PIOCNMAP, &nmaps) < 0)
> -     proc_error (pi, "proc_iterate_over_mappings (PIOCNMAP)", __LINE__);
> -
> -   /* Allocate space for mappings (lifetime only this function).  */
> -   map = (struct prmap *) alloca ((nmaps + 1) * sizeof (struct prmap));
> -
> -   /* Read in all the mappings.  */
> -   if (ioctl (pi->ctl_fd, PIOCMAP, map) < 0)
> -     proc_error (pi, "proc_iterate_over_mappings (PIOCMAP)", __LINE__);
> -
> -   /* Now loop through the mappings, open an fd for each, and
> -      call the callback function.  */
> -   for (i = 0;
> -        i < nmaps && map[i].pr_size != 0;
> -        i++)
> -     {
> -       /* Note: caller's responsibility to close this fd!  */
> -       fd = ioctl (pi->ctl_fd, PIOCOPENM, &map[i].pr_vaddr);
> -       /* Note: we don't test the above call for failure;
> -        we just pass the FD on as given.  Sometimes there is
> -        no file, so the ioctl may return failure, but that's
> -        not a problem.  */
> -
> -       /* Stop looping if the callback returns non-zero.  */
> -       funcstat = (*func) (fd, host_pointer_to_address (map[i].pr_vaddr));
> -       if (funcstat != 0)
> -       break;
> -     }
> - #endif
> -
> -   return funcstat;
> - }
> -
>   #ifdef TM_I386SOL2_H          /* Is it hokey to use this? */
> 
>   #include <sys/sysi86.h>
> --- 2869,2874 ----
> *************** procfs_find_LDT_entry (ptid_t ptid)
> *** 5308,5313 ****
> --- 5203,5360 ----
>   #endif /* TM_I386SOL2_H */
> 
>   /*
> +  * Memory Mappings Functions:
> +  */
> +
> + /*
> +  * Function: iterate_over_mappings
> +  *
> +  * Call a callback function once for each mapping, passing it the mapping,
> +  * an optional secondary callback function, and some optional opaque data.
> +  * Quit and return the first non-zero value returned from the callback.
> +  *
> +  * Arguments:
> +  *   pi   -- procinfo struct for the process to be mapped.
> +  *   func -- callback function to be called by this iterator.
> +  *   data -- optional opaque data to be passed to the callback function.
> +  *   child_func -- optional secondary function pointer to be passed
> +  *                 to the child function.
> +  *
> +  * Return: First non-zero return value from the callback function,
> +  *         or zero.
> +  */
> +
> + static int
> + iterate_over_mappings (procinfo *pi, int (*child_func) (), void *data,
> +                      int (*func) (struct prmap *map,
> +                                   int (*child_func) (),
> +                                   void *data))
> + {
> +   char pathname[MAX_PROC_NAME_SIZE];
> +   struct prmap *prmaps;
> +   struct prmap *prmap;
> +   int funcstat;
> +   int map_fd;
> +   int nmap;
> + #ifdef NEW_PROC_API
> +   struct stat sbuf;
> + #endif
> +
> +   /* Get the number of mappings, allocate space,
> +      and read the mappings into prmaps.  */
> + #ifdef NEW_PROC_API
> +   /* Open map fd. */
> +   sprintf (pathname, "/proc/%d/map", pi->pid);
> +   if ((map_fd = open (pathname, O_RDONLY)) < 0)
> +     proc_error (pi, "iterate_over_mappings (open)", __LINE__);
> +
> +   /* Make sure it gets closed again. */
> +   make_cleanup_close (map_fd);
> +
> +   /* Use stat to determine the file size, and compute
> +      the number of prmap_t objects it contains.  */
> +   if (fstat (map_fd, &sbuf) != 0)
> +     proc_error (pi, "iterate_over_mappings (fstat)", __LINE__);
> +
> +   nmap = sbuf.st_size / sizeof (prmap_t);
> +   prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
> +   if (read (map_fd, (char *) prmaps, nmap * sizeof (*prmaps))
> +       != (nmap * sizeof (*prmaps)))
> +     proc_error (pi, "iterate_over_mappings (read)", __LINE__);
> + #else
> +   /* Use ioctl command PIOCNMAP to get number of mappings.  */
> +   if (ioctl (pi->ctl_fd, PIOCNMAP, &nmap) != 0)
> +     proc_error (pi, "iterate_over_mappings (PIOCNMAP)", __LINE__);
> +
> +   prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
> +   if (ioctl (pi->ctl_fd, PIOCMAP, prmaps) != 0)
> +     proc_error (pi, "iterate_over_mappings (PIOCMAP)", __LINE__);
> + #endif
> +
> +   for (prmap = prmaps; nmap > 0; prmap++, nmap--)
> +     if ((funcstat = (*func) (prmap, child_func, data)) != 0)
> +       return funcstat;
> +
> +   return 0;
> + }
> +
> + /*
> +  * Function: solib_mappings_callback
> +  *
> +  * Calls the supplied callback function once for each mapped address
> +  * space in the process.  The callback function  receives an open
> +  * file descriptor for the file corresponding to that mapped
> +  * address space (if there is one), and the base address of the
> +  * mapped space.  Quit when the callback function returns a
> +  * nonzero value, or at teh end of the mappings.
> +  *
> +  * Returns: the first non-zero return value of the callback function,
> +  * or zero.
> +  */
> +
> + int solib_mappings_callback (struct prmap *map,
> +                            int (*func) (int, CORE_ADDR),
> +                            void *data)
> + {
> +   procinfo *pi = data;
> +   int fd;
> +
> + #ifdef NEW_PROC_API
> +   char name[MAX_PROC_NAME_SIZE + sizeof (map->pr_mapname)];
> +
> +   if (map->pr_vaddr == 0 && map->pr_size == 0)
> +     return -1;                /* sanity */
> +
> +   if (map->pr_mapname[0] == 0)
> +     {
> +       fd = -1;        /* no map file */
> +     }
> +   else
> +     {
> +       sprintf (name, "/proc/%d/object/%s", pi->pid, map->pr_mapname);
> +       /* Note: caller's responsibility to close this fd!  */
> +       fd = open_with_retry (name, O_RDONLY);
> +       /* Note: we don't test the above call for failure;
> +        we just pass the FD on as given.  Sometimes there is
> +        no file, so the open may return failure, but that's
> +        not a problem.  */
> +     }
> + #else
> +   fd = ioctl (pi->ctl_fd, PIOCOPENM, &map->pr_vaddr);
> +   /* Note: we don't test the above call for failure;
> +      we just pass the FD on as given.  Sometimes there is
> +      no file, so the ioctl may return failure, but that's
> +      not a problem.  */
> + #endif
> +   return (*func) (fd, (CORE_ADDR) map->pr_vaddr);
> + }
> +
> + /*
> +  * Function: proc_iterate_over_mappings
> +  *
> +  * Uses the unified "iterate_over_mappings" function
> +  * to implement the exported interface to solib-svr4.c.
> +  *
> +  * Given a pointer to a function, call that function once for every
> +  * mapped address space in the process.  The callback function
> +  * receives an open file descriptor for the file corresponding to
> +  * that mapped address space (if there is one), and the base address
> +  * of the mapped space.  Quit when the callback function returns a
> +  * nonzero value, or at teh end of the mappings.
> +  *
> +  * Returns: the first non-zero return value of the callback function,
> +  * or zero.
> +  */
> +
> + int
> + proc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
> + {
> +   procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
> +
> +   return iterate_over_mappings (pi, func, pi, solib_mappings_callback);
> + }
> +
> + /*
>    * Function: mappingflags
>    *
>    * Returns an ascii representation of a memory mapping's flags.
> *************** mappingflags (flags)
> *** 5340,5345 ****
> --- 5387,5423 ----
>   }
> 
>   /*
> +  * Function: info_mappings_callback
> +  *
> +  * Callback function, does the actual work for 'info proc mappings'.
> +  */
> +
> + /* ARGSUSED */
> + static int
> + info_mappings_callback (struct prmap *map, int (*ignore) (), void *unused)
> + {
> +   char *data_fmt_string;
> +
> +   if (TARGET_ADDR_BIT == 32)
> +     data_fmt_string   = "\t%#10lx %#10lx %#10x %#10x %7s\n";
> +   else
> +     data_fmt_string   = "  %#18lx %#18lx %#10x %#10x %7s\n";
> +
> +   printf_filtered (data_fmt_string,
> +                  (unsigned long) map->pr_vaddr,
> +                  (unsigned long) map->pr_vaddr + map->pr_size - 1,
> +                  map->pr_size,
> + #ifdef PCAGENT        /* Horrible hack: only defined on Solaris 2.6+ */
> +                  (unsigned int) map->pr_offset,
> + #else
> +                  map->pr_off,
> + #endif
> +                  mappingflags (map->pr_mflags));
> +
> +   return 0;
> + }
> +
> + /*
>    * Function: info_proc_mappings
>    *
>    * Implement the "info proc mappings" subcommand.
> *************** mappingflags (flags)
> *** 5348,5406 ****
>   static void
>   info_proc_mappings (procinfo *pi, int summary)
>   {
> !   char *header_fmt_string, *data_fmt_string;
> !   char pathname[MAX_PROC_NAME_SIZE];
> !   struct prmap *prmaps;
> !   struct prmap *prmap;
> !   int map_fd;
> !   int nmap;
> ! #ifdef NEW_PROC_API
> !   struct stat sbuf;
> ! #endif
> 
>     if (TARGET_PTR_BIT == 32)
> !     {
> !       header_fmt_string = "\t%10s %10s %10s %10s %7s\n";
> !       data_fmt_string   = "\t%#10lx %#10lx %#10x %#10x %7s\n";
> !     }
>     else
> !     {
> !       header_fmt_string = "  %18s %18s %10s %10s %7s\n";
> !       data_fmt_string   = "  %#18lx %#18lx %#10x %#10x %7s\n";
> !     }
> 
>     if (summary)
>       return;   /* No output for summary mode. */
> 
> -   /* Get the number of mappings, allocate space,
> -      and read the mappings into prmaps.  */
> - #ifdef NEW_PROC_API
> -   /* Open map fd. */
> -   sprintf (pathname, "/proc/%d/map", pi->pid);
> -   if ((map_fd = open (pathname, O_RDONLY)) < 0)
> -     return;           /* Can't open map file. */
> -   /* Make sure it gets closed again. */
> -   make_cleanup_close (map_fd);
> -
> -   /* Use stat to determine the file size, and compute
> -      the number of prmap_t objects it contains.  */
> -   if (fstat (map_fd, &sbuf) != 0)
> -     return;           /* Can't stat file.  */
> -
> -   nmap = sbuf.st_size / sizeof (prmap_t);
> -   prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
> -   if (read (map_fd, (char *) prmaps, nmap * sizeof (*prmaps))
> -       != (nmap * sizeof (*prmaps)))
> -     return;           /* Can't read file. */
> - #else
> -   /* Use ioctl command PIOCNMAP to get number of mappings.  */
> -   if (ioctl (pi->ctl_fd, PIOCNMAP, &nmap) != 0)
> -     return;   /* Can't get number of mappings.  */
> -   prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
> -   if (ioctl (pi->ctl_fd, PIOCMAP, prmaps) != 0)
> -     return;   /* Can't read mappings. */
> - #endif
> -
>     printf_filtered ("Mapped address spaces:\n\n");
>     printf_filtered (header_fmt_string,
>                    "Start Addr",
> --- 5426,5441 ----
>   static void
>   info_proc_mappings (procinfo *pi, int summary)
>   {
> !   char *header_fmt_string;
> 
>     if (TARGET_PTR_BIT == 32)
> !     header_fmt_string = "\t%10s %10s %10s %10s %7s\n";
>     else
> !     header_fmt_string = "  %18s %18s %10s %10s %7s\n";
> 
>     if (summary)
>       return;   /* No output for summary mode. */
> 
>     printf_filtered ("Mapped address spaces:\n\n");
>     printf_filtered (header_fmt_string,
>                    "Start Addr",
> *************** info_proc_mappings (procinfo *pi, int su
> *** 5409,5428 ****
>                    "    Offset",
>                    "Flags");
> 
> !   for (prmap = prmaps; nmap > 0; prmap++, nmap--)
> !     {
> !       printf_filtered (data_fmt_string,
> !                      (unsigned long) prmap->pr_vaddr,
> !                      (unsigned long) prmap->pr_vaddr
> !                      + prmap->pr_size - 1,
> !                      prmap->pr_size,
> ! #ifdef PCAGENT                /* Gross hack: only defined on Solaris 2.6+ */
> !                      (unsigned int) prmap->pr_offset,
> ! #else
> !                      prmap->pr_off,
> ! #endif
> !                      mappingflags (prmap->pr_mflags));
> !     }
>     printf_filtered ("\n");
>   }
> 
> --- 5444,5450 ----
>                    "    Offset",
>                    "Flags");
> 
> !   iterate_over_mappings (pi, NULL, NULL, info_mappings_callback);
>     printf_filtered ("\n");
>   }
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]