xref: /dflybsd-src/contrib/gdb-7/gdb/corefile.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Core dump and executable file functions above target vector, for GDB.
25796c8dcSSimon Schubert 
3*ef5ccd6cSJohn Marino    Copyright (C) 1986-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    This file is part of GDB.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert    (at your option) any later version.
115796c8dcSSimon Schubert 
125796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155796c8dcSSimon Schubert    GNU General Public License for more details.
165796c8dcSSimon Schubert 
175796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
195796c8dcSSimon Schubert 
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert #include "gdb_string.h"
225796c8dcSSimon Schubert #include <errno.h>
235796c8dcSSimon Schubert #include <signal.h>
245796c8dcSSimon Schubert #include <fcntl.h>
255796c8dcSSimon Schubert #include "inferior.h"
265796c8dcSSimon Schubert #include "symtab.h"
275796c8dcSSimon Schubert #include "command.h"
285796c8dcSSimon Schubert #include "gdbcmd.h"
295796c8dcSSimon Schubert #include "bfd.h"
305796c8dcSSimon Schubert #include "target.h"
315796c8dcSSimon Schubert #include "gdbcore.h"
325796c8dcSSimon Schubert #include "dis-asm.h"
335796c8dcSSimon Schubert #include "gdb_stat.h"
345796c8dcSSimon Schubert #include "completer.h"
355796c8dcSSimon Schubert #include "exceptions.h"
36*ef5ccd6cSJohn Marino #include "observer.h"
37*ef5ccd6cSJohn Marino #include "cli/cli-utils.h"
385796c8dcSSimon Schubert 
395796c8dcSSimon Schubert /* Local function declarations.  */
405796c8dcSSimon Schubert 
415796c8dcSSimon Schubert extern void _initialize_core (void);
425796c8dcSSimon Schubert static void call_extra_exec_file_hooks (char *filename);
435796c8dcSSimon Schubert 
445796c8dcSSimon Schubert /* You can have any number of hooks for `exec_file_command' command to
455796c8dcSSimon Schubert    call.  If there's only one hook, it is set in exec_file_display
465796c8dcSSimon Schubert    hook.  If there are two or more hooks, they are set in
475796c8dcSSimon Schubert    exec_file_extra_hooks[], and deprecated_exec_file_display_hook is
485796c8dcSSimon Schubert    set to a function that calls all of them.  This extra complexity is
495796c8dcSSimon Schubert    needed to preserve compatibility with old code that assumed that
505796c8dcSSimon Schubert    only one hook could be set, and which called
515796c8dcSSimon Schubert    deprecated_exec_file_display_hook directly.  */
525796c8dcSSimon Schubert 
535796c8dcSSimon Schubert typedef void (*hook_type) (char *);
545796c8dcSSimon Schubert 
55c50c785cSJohn Marino hook_type deprecated_exec_file_display_hook;	/* The original hook.  */
56c50c785cSJohn Marino static hook_type *exec_file_extra_hooks;	/* Array of additional
57c50c785cSJohn Marino 						   hooks.  */
58c50c785cSJohn Marino static int exec_file_hook_count = 0;		/* Size of array.  */
595796c8dcSSimon Schubert 
605796c8dcSSimon Schubert /* Binary file diddling handle for the core file.  */
615796c8dcSSimon Schubert 
625796c8dcSSimon Schubert bfd *core_bfd = NULL;
63c50c785cSJohn Marino 
64*ef5ccd6cSJohn Marino /* corelow.c target.  It is never NULL after GDB initialization.  */
65c50c785cSJohn Marino 
66c50c785cSJohn Marino struct target_ops *core_target;
675796c8dcSSimon Schubert 
685796c8dcSSimon Schubert 
695796c8dcSSimon Schubert /* Backward compatability with old way of specifying core files.  */
705796c8dcSSimon Schubert 
715796c8dcSSimon Schubert void
core_file_command(char * filename,int from_tty)725796c8dcSSimon Schubert core_file_command (char *filename, int from_tty)
735796c8dcSSimon Schubert {
745796c8dcSSimon Schubert   dont_repeat ();		/* Either way, seems bogus.  */
755796c8dcSSimon Schubert 
76*ef5ccd6cSJohn Marino   gdb_assert (core_target != NULL);
775796c8dcSSimon Schubert 
785796c8dcSSimon Schubert   if (!filename)
79c50c785cSJohn Marino     (core_target->to_detach) (core_target, filename, from_tty);
805796c8dcSSimon Schubert   else
81c50c785cSJohn Marino     (core_target->to_open) (filename, from_tty);
825796c8dcSSimon Schubert }
835796c8dcSSimon Schubert 
845796c8dcSSimon Schubert 
855796c8dcSSimon Schubert /* If there are two or more functions that wish to hook into
865796c8dcSSimon Schubert    exec_file_command, this function will call all of the hook
875796c8dcSSimon Schubert    functions.  */
885796c8dcSSimon Schubert 
895796c8dcSSimon Schubert static void
call_extra_exec_file_hooks(char * filename)905796c8dcSSimon Schubert call_extra_exec_file_hooks (char *filename)
915796c8dcSSimon Schubert {
925796c8dcSSimon Schubert   int i;
935796c8dcSSimon Schubert 
945796c8dcSSimon Schubert   for (i = 0; i < exec_file_hook_count; i++)
955796c8dcSSimon Schubert     (*exec_file_extra_hooks[i]) (filename);
965796c8dcSSimon Schubert }
975796c8dcSSimon Schubert 
985796c8dcSSimon Schubert /* Call this to specify the hook for exec_file_command to call back.
995796c8dcSSimon Schubert    This is called from the x-window display code.  */
1005796c8dcSSimon Schubert 
1015796c8dcSSimon Schubert void
specify_exec_file_hook(void (* hook)(char *))1025796c8dcSSimon Schubert specify_exec_file_hook (void (*hook) (char *))
1035796c8dcSSimon Schubert {
1045796c8dcSSimon Schubert   hook_type *new_array;
1055796c8dcSSimon Schubert 
1065796c8dcSSimon Schubert   if (deprecated_exec_file_display_hook != NULL)
1075796c8dcSSimon Schubert     {
1085796c8dcSSimon Schubert       /* There's already a hook installed.  Arrange to have both it
109c50c785cSJohn Marino 	 and the subsequent hooks called.  */
1105796c8dcSSimon Schubert       if (exec_file_hook_count == 0)
1115796c8dcSSimon Schubert 	{
112c50c785cSJohn Marino 	  /* If this is the first extra hook, initialize the hook
113c50c785cSJohn Marino 	     array.  */
114c50c785cSJohn Marino 	  exec_file_extra_hooks = (hook_type *)
115c50c785cSJohn Marino 	    xmalloc (sizeof (hook_type));
1165796c8dcSSimon Schubert 	  exec_file_extra_hooks[0] = deprecated_exec_file_display_hook;
1175796c8dcSSimon Schubert 	  deprecated_exec_file_display_hook = call_extra_exec_file_hooks;
1185796c8dcSSimon Schubert 	  exec_file_hook_count = 1;
1195796c8dcSSimon Schubert 	}
1205796c8dcSSimon Schubert 
1215796c8dcSSimon Schubert       /* Grow the hook array by one and add the new hook to the end.
1225796c8dcSSimon Schubert          Yes, it's inefficient to grow it by one each time but since
1235796c8dcSSimon Schubert          this is hardly ever called it's not a big deal.  */
1245796c8dcSSimon Schubert       exec_file_hook_count++;
125c50c785cSJohn Marino       new_array = (hook_type *)
126c50c785cSJohn Marino 	xrealloc (exec_file_extra_hooks,
1275796c8dcSSimon Schubert 		  exec_file_hook_count * sizeof (hook_type));
1285796c8dcSSimon Schubert       exec_file_extra_hooks = new_array;
1295796c8dcSSimon Schubert       exec_file_extra_hooks[exec_file_hook_count - 1] = hook;
1305796c8dcSSimon Schubert     }
1315796c8dcSSimon Schubert   else
1325796c8dcSSimon Schubert     deprecated_exec_file_display_hook = hook;
1335796c8dcSSimon Schubert }
1345796c8dcSSimon Schubert 
1355796c8dcSSimon Schubert void
reopen_exec_file(void)1365796c8dcSSimon Schubert reopen_exec_file (void)
1375796c8dcSSimon Schubert {
1385796c8dcSSimon Schubert   char *filename;
1395796c8dcSSimon Schubert   int res;
1405796c8dcSSimon Schubert   struct stat st;
1415796c8dcSSimon Schubert   struct cleanup *cleanups;
1425796c8dcSSimon Schubert 
1435796c8dcSSimon Schubert   /* Don't do anything if there isn't an exec file.  */
1445796c8dcSSimon Schubert   if (exec_bfd == NULL)
1455796c8dcSSimon Schubert     return;
1465796c8dcSSimon Schubert 
1475796c8dcSSimon Schubert   /* If the timestamp of the exec file has changed, reopen it.  */
1485796c8dcSSimon Schubert   filename = xstrdup (bfd_get_filename (exec_bfd));
1495796c8dcSSimon Schubert   cleanups = make_cleanup (xfree, filename);
1505796c8dcSSimon Schubert   res = stat (filename, &st);
1515796c8dcSSimon Schubert 
1525796c8dcSSimon Schubert   if (exec_bfd_mtime && exec_bfd_mtime != st.st_mtime)
1535796c8dcSSimon Schubert     exec_file_attach (filename, 0);
1545796c8dcSSimon Schubert   else
1555796c8dcSSimon Schubert     /* If we accessed the file since last opening it, close it now;
1565796c8dcSSimon Schubert        this stops GDB from holding the executable open after it
1575796c8dcSSimon Schubert        exits.  */
1585796c8dcSSimon Schubert     bfd_cache_close_all ();
1595796c8dcSSimon Schubert 
1605796c8dcSSimon Schubert   do_cleanups (cleanups);
1615796c8dcSSimon Schubert }
1625796c8dcSSimon Schubert 
1635796c8dcSSimon Schubert /* If we have both a core file and an exec file,
1645796c8dcSSimon Schubert    print a warning if they don't go together.  */
1655796c8dcSSimon Schubert 
1665796c8dcSSimon Schubert void
validate_files(void)1675796c8dcSSimon Schubert validate_files (void)
1685796c8dcSSimon Schubert {
1695796c8dcSSimon Schubert   if (exec_bfd && core_bfd)
1705796c8dcSSimon Schubert     {
1715796c8dcSSimon Schubert       if (!core_file_matches_executable_p (core_bfd, exec_bfd))
1725796c8dcSSimon Schubert 	warning (_("core file may not match specified executable file."));
1735796c8dcSSimon Schubert       else if (bfd_get_mtime (exec_bfd) > bfd_get_mtime (core_bfd))
1745796c8dcSSimon Schubert 	warning (_("exec file is newer than core file."));
1755796c8dcSSimon Schubert     }
1765796c8dcSSimon Schubert }
1775796c8dcSSimon Schubert 
1785796c8dcSSimon Schubert /* Return the name of the executable file as a string.
1795796c8dcSSimon Schubert    ERR nonzero means get error if there is none specified;
1805796c8dcSSimon Schubert    otherwise return 0 in that case.  */
1815796c8dcSSimon Schubert 
1825796c8dcSSimon Schubert char *
get_exec_file(int err)1835796c8dcSSimon Schubert get_exec_file (int err)
1845796c8dcSSimon Schubert {
185*ef5ccd6cSJohn Marino   if (exec_filename)
186*ef5ccd6cSJohn Marino     return exec_filename;
1875796c8dcSSimon Schubert   if (!err)
1885796c8dcSSimon Schubert     return NULL;
1895796c8dcSSimon Schubert 
1905796c8dcSSimon Schubert   error (_("No executable file specified.\n\
1915796c8dcSSimon Schubert Use the \"file\" or \"exec-file\" command."));
1925796c8dcSSimon Schubert   return NULL;
1935796c8dcSSimon Schubert }
1945796c8dcSSimon Schubert 
1955796c8dcSSimon Schubert 
1965796c8dcSSimon Schubert /* Report a memory error by throwing a MEMORY_ERROR error.  */
1975796c8dcSSimon Schubert 
1985796c8dcSSimon Schubert void
memory_error(int status,CORE_ADDR memaddr)1995796c8dcSSimon Schubert memory_error (int status, CORE_ADDR memaddr)
2005796c8dcSSimon Schubert {
2015796c8dcSSimon Schubert   if (status == EIO)
2025796c8dcSSimon Schubert     /* Actually, address between memaddr and memaddr + len was out of
2035796c8dcSSimon Schubert        bounds.  */
2045796c8dcSSimon Schubert     throw_error (MEMORY_ERROR,
2055796c8dcSSimon Schubert 		 _("Cannot access memory at address %s"),
206*ef5ccd6cSJohn Marino 		 paddress (target_gdbarch (), memaddr));
2075796c8dcSSimon Schubert   else
2085796c8dcSSimon Schubert     throw_error (MEMORY_ERROR,
2095796c8dcSSimon Schubert 		 _("Error accessing memory address %s: %s."),
210*ef5ccd6cSJohn Marino 		 paddress (target_gdbarch (), memaddr),
2115796c8dcSSimon Schubert 		 safe_strerror (status));
2125796c8dcSSimon Schubert }
2135796c8dcSSimon Schubert 
2145796c8dcSSimon Schubert /* Same as target_read_memory, but report an error if can't read.  */
2155796c8dcSSimon Schubert 
2165796c8dcSSimon Schubert void
read_memory(CORE_ADDR memaddr,gdb_byte * myaddr,ssize_t len)217*ef5ccd6cSJohn Marino read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
2185796c8dcSSimon Schubert {
2195796c8dcSSimon Schubert   int status;
220cf7f2e2dSJohn Marino 
2215796c8dcSSimon Schubert   status = target_read_memory (memaddr, myaddr, len);
2225796c8dcSSimon Schubert   if (status != 0)
2235796c8dcSSimon Schubert     memory_error (status, memaddr);
2245796c8dcSSimon Schubert }
2255796c8dcSSimon Schubert 
2265796c8dcSSimon Schubert /* Same as target_read_stack, but report an error if can't read.  */
2275796c8dcSSimon Schubert 
2285796c8dcSSimon Schubert void
read_stack(CORE_ADDR memaddr,gdb_byte * myaddr,ssize_t len)229*ef5ccd6cSJohn Marino read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
2305796c8dcSSimon Schubert {
2315796c8dcSSimon Schubert   int status;
232cf7f2e2dSJohn Marino 
2335796c8dcSSimon Schubert   status = target_read_stack (memaddr, myaddr, len);
2345796c8dcSSimon Schubert   if (status != 0)
2355796c8dcSSimon Schubert     memory_error (status, memaddr);
2365796c8dcSSimon Schubert }
2375796c8dcSSimon Schubert 
2385796c8dcSSimon Schubert /* Argument / return result struct for use with
2395796c8dcSSimon Schubert    do_captured_read_memory_integer().  MEMADDR and LEN are filled in
2405796c8dcSSimon Schubert    by gdb_read_memory_integer().  RESULT is the contents that were
2415796c8dcSSimon Schubert    successfully read from MEMADDR of length LEN.  */
2425796c8dcSSimon Schubert 
2435796c8dcSSimon Schubert struct captured_read_memory_integer_arguments
2445796c8dcSSimon Schubert {
2455796c8dcSSimon Schubert   CORE_ADDR memaddr;
2465796c8dcSSimon Schubert   int len;
2475796c8dcSSimon Schubert   enum bfd_endian byte_order;
2485796c8dcSSimon Schubert   LONGEST result;
2495796c8dcSSimon Schubert };
2505796c8dcSSimon Schubert 
2515796c8dcSSimon Schubert /* Helper function for gdb_read_memory_integer().  DATA must be a
2525796c8dcSSimon Schubert    pointer to a captured_read_memory_integer_arguments struct.
2535796c8dcSSimon Schubert    Return 1 if successful.  Note that the catch_errors() interface
2545796c8dcSSimon Schubert    will return 0 if an error occurred while reading memory.  This
2555796c8dcSSimon Schubert    choice of return code is so that we can distinguish between
2565796c8dcSSimon Schubert    success and failure.  */
2575796c8dcSSimon Schubert 
2585796c8dcSSimon Schubert static int
do_captured_read_memory_integer(void * data)2595796c8dcSSimon Schubert do_captured_read_memory_integer (void *data)
2605796c8dcSSimon Schubert {
261c50c785cSJohn Marino   struct captured_read_memory_integer_arguments *args
262c50c785cSJohn Marino     = (struct captured_read_memory_integer_arguments*) data;
2635796c8dcSSimon Schubert   CORE_ADDR memaddr = args->memaddr;
2645796c8dcSSimon Schubert   int len = args->len;
2655796c8dcSSimon Schubert   enum bfd_endian byte_order = args->byte_order;
2665796c8dcSSimon Schubert 
2675796c8dcSSimon Schubert   args->result = read_memory_integer (memaddr, len, byte_order);
2685796c8dcSSimon Schubert 
2695796c8dcSSimon Schubert   return 1;
2705796c8dcSSimon Schubert }
2715796c8dcSSimon Schubert 
2725796c8dcSSimon Schubert /* Read memory at MEMADDR of length LEN and put the contents in
2735796c8dcSSimon Schubert    RETURN_VALUE.  Return 0 if MEMADDR couldn't be read and non-zero
2745796c8dcSSimon Schubert    if successful.  */
2755796c8dcSSimon Schubert 
2765796c8dcSSimon Schubert int
safe_read_memory_integer(CORE_ADDR memaddr,int len,enum bfd_endian byte_order,LONGEST * return_value)277cf7f2e2dSJohn Marino safe_read_memory_integer (CORE_ADDR memaddr, int len,
278cf7f2e2dSJohn Marino 			  enum bfd_endian byte_order,
2795796c8dcSSimon Schubert 			  LONGEST *return_value)
2805796c8dcSSimon Schubert {
2815796c8dcSSimon Schubert   int status;
2825796c8dcSSimon Schubert   struct captured_read_memory_integer_arguments args;
283cf7f2e2dSJohn Marino 
2845796c8dcSSimon Schubert   args.memaddr = memaddr;
2855796c8dcSSimon Schubert   args.len = len;
2865796c8dcSSimon Schubert   args.byte_order = byte_order;
2875796c8dcSSimon Schubert 
2885796c8dcSSimon Schubert   status = catch_errors (do_captured_read_memory_integer, &args,
2895796c8dcSSimon Schubert 			 "", RETURN_MASK_ALL);
2905796c8dcSSimon Schubert   if (status)
2915796c8dcSSimon Schubert     *return_value = args.result;
2925796c8dcSSimon Schubert 
2935796c8dcSSimon Schubert   return status;
2945796c8dcSSimon Schubert }
2955796c8dcSSimon Schubert 
2965796c8dcSSimon Schubert LONGEST
read_memory_integer(CORE_ADDR memaddr,int len,enum bfd_endian byte_order)297c50c785cSJohn Marino read_memory_integer (CORE_ADDR memaddr, int len,
298c50c785cSJohn Marino 		     enum bfd_endian byte_order)
2995796c8dcSSimon Schubert {
3005796c8dcSSimon Schubert   gdb_byte buf[sizeof (LONGEST)];
3015796c8dcSSimon Schubert 
3025796c8dcSSimon Schubert   read_memory (memaddr, buf, len);
3035796c8dcSSimon Schubert   return extract_signed_integer (buf, len, byte_order);
3045796c8dcSSimon Schubert }
3055796c8dcSSimon Schubert 
3065796c8dcSSimon Schubert ULONGEST
read_memory_unsigned_integer(CORE_ADDR memaddr,int len,enum bfd_endian byte_order)307c50c785cSJohn Marino read_memory_unsigned_integer (CORE_ADDR memaddr, int len,
308c50c785cSJohn Marino 			      enum bfd_endian byte_order)
3095796c8dcSSimon Schubert {
3105796c8dcSSimon Schubert   gdb_byte buf[sizeof (ULONGEST)];
3115796c8dcSSimon Schubert 
3125796c8dcSSimon Schubert   read_memory (memaddr, buf, len);
3135796c8dcSSimon Schubert   return extract_unsigned_integer (buf, len, byte_order);
3145796c8dcSSimon Schubert }
3155796c8dcSSimon Schubert 
3165796c8dcSSimon Schubert void
read_memory_string(CORE_ADDR memaddr,char * buffer,int max_len)3175796c8dcSSimon Schubert read_memory_string (CORE_ADDR memaddr, char *buffer, int max_len)
3185796c8dcSSimon Schubert {
3195796c8dcSSimon Schubert   char *cp;
3205796c8dcSSimon Schubert   int i;
3215796c8dcSSimon Schubert   int cnt;
3225796c8dcSSimon Schubert 
3235796c8dcSSimon Schubert   cp = buffer;
3245796c8dcSSimon Schubert   while (1)
3255796c8dcSSimon Schubert     {
3265796c8dcSSimon Schubert       if (cp - buffer >= max_len)
3275796c8dcSSimon Schubert 	{
3285796c8dcSSimon Schubert 	  buffer[max_len - 1] = '\0';
3295796c8dcSSimon Schubert 	  break;
3305796c8dcSSimon Schubert 	}
3315796c8dcSSimon Schubert       cnt = max_len - (cp - buffer);
3325796c8dcSSimon Schubert       if (cnt > 8)
3335796c8dcSSimon Schubert 	cnt = 8;
334*ef5ccd6cSJohn Marino       read_memory (memaddr + (int) (cp - buffer), (gdb_byte *) cp, cnt);
3355796c8dcSSimon Schubert       for (i = 0; i < cnt && *cp; i++, cp++)
3365796c8dcSSimon Schubert 	;			/* null body */
3375796c8dcSSimon Schubert 
3385796c8dcSSimon Schubert       if (i < cnt && !*cp)
3395796c8dcSSimon Schubert 	break;
3405796c8dcSSimon Schubert     }
3415796c8dcSSimon Schubert }
3425796c8dcSSimon Schubert 
3435796c8dcSSimon Schubert CORE_ADDR
read_memory_typed_address(CORE_ADDR addr,struct type * type)3445796c8dcSSimon Schubert read_memory_typed_address (CORE_ADDR addr, struct type *type)
3455796c8dcSSimon Schubert {
3465796c8dcSSimon Schubert   gdb_byte *buf = alloca (TYPE_LENGTH (type));
347cf7f2e2dSJohn Marino 
3485796c8dcSSimon Schubert   read_memory (addr, buf, TYPE_LENGTH (type));
3495796c8dcSSimon Schubert   return extract_typed_address (buf, type);
3505796c8dcSSimon Schubert }
3515796c8dcSSimon Schubert 
352c50c785cSJohn Marino /* Same as target_write_memory, but report an error if can't
353c50c785cSJohn Marino    write.  */
3545796c8dcSSimon Schubert void
write_memory(CORE_ADDR memaddr,const bfd_byte * myaddr,ssize_t len)355c50c785cSJohn Marino write_memory (CORE_ADDR memaddr,
356*ef5ccd6cSJohn Marino 	      const bfd_byte *myaddr, ssize_t len)
3575796c8dcSSimon Schubert {
3585796c8dcSSimon Schubert   int status;
359cf7f2e2dSJohn Marino 
3605796c8dcSSimon Schubert   status = target_write_memory (memaddr, myaddr, len);
3615796c8dcSSimon Schubert   if (status != 0)
3625796c8dcSSimon Schubert     memory_error (status, memaddr);
3635796c8dcSSimon Schubert }
3645796c8dcSSimon Schubert 
365*ef5ccd6cSJohn Marino /* Same as write_memory, but notify 'memory_changed' observers.  */
366*ef5ccd6cSJohn Marino 
367*ef5ccd6cSJohn Marino void
write_memory_with_notification(CORE_ADDR memaddr,const bfd_byte * myaddr,ssize_t len)368*ef5ccd6cSJohn Marino write_memory_with_notification (CORE_ADDR memaddr, const bfd_byte *myaddr,
369*ef5ccd6cSJohn Marino 				ssize_t len)
370*ef5ccd6cSJohn Marino {
371*ef5ccd6cSJohn Marino   write_memory (memaddr, myaddr, len);
372*ef5ccd6cSJohn Marino   observer_notify_memory_changed (current_inferior (), memaddr, len, myaddr);
373*ef5ccd6cSJohn Marino }
374*ef5ccd6cSJohn Marino 
375c50c785cSJohn Marino /* Store VALUE at ADDR in the inferior as a LEN-byte unsigned
376c50c785cSJohn Marino    integer.  */
3775796c8dcSSimon Schubert void
write_memory_unsigned_integer(CORE_ADDR addr,int len,enum bfd_endian byte_order,ULONGEST value)378cf7f2e2dSJohn Marino write_memory_unsigned_integer (CORE_ADDR addr, int len,
379cf7f2e2dSJohn Marino 			       enum bfd_endian byte_order,
3805796c8dcSSimon Schubert 			       ULONGEST value)
3815796c8dcSSimon Schubert {
3825796c8dcSSimon Schubert   gdb_byte *buf = alloca (len);
383cf7f2e2dSJohn Marino 
3845796c8dcSSimon Schubert   store_unsigned_integer (buf, len, byte_order, value);
3855796c8dcSSimon Schubert   write_memory (addr, buf, len);
3865796c8dcSSimon Schubert }
3875796c8dcSSimon Schubert 
388c50c785cSJohn Marino /* Store VALUE at ADDR in the inferior as a LEN-byte signed
389c50c785cSJohn Marino    integer.  */
3905796c8dcSSimon Schubert void
write_memory_signed_integer(CORE_ADDR addr,int len,enum bfd_endian byte_order,LONGEST value)391cf7f2e2dSJohn Marino write_memory_signed_integer (CORE_ADDR addr, int len,
392cf7f2e2dSJohn Marino 			     enum bfd_endian byte_order,
3935796c8dcSSimon Schubert 			     LONGEST value)
3945796c8dcSSimon Schubert {
3955796c8dcSSimon Schubert   gdb_byte *buf = alloca (len);
396cf7f2e2dSJohn Marino 
3975796c8dcSSimon Schubert   store_signed_integer (buf, len, byte_order, value);
3985796c8dcSSimon Schubert   write_memory (addr, buf, len);
3995796c8dcSSimon Schubert }
4005796c8dcSSimon Schubert 
4015796c8dcSSimon Schubert /* The current default bfd target.  Points to storage allocated for
4025796c8dcSSimon Schubert    gnutarget_string.  */
4035796c8dcSSimon Schubert char *gnutarget;
4045796c8dcSSimon Schubert 
4055796c8dcSSimon Schubert /* Same thing, except it is "auto" not NULL for the default case.  */
4065796c8dcSSimon Schubert static char *gnutarget_string;
4075796c8dcSSimon Schubert static void
show_gnutarget_string(struct ui_file * file,int from_tty,struct cmd_list_element * c,const char * value)4085796c8dcSSimon Schubert show_gnutarget_string (struct ui_file *file, int from_tty,
409c50c785cSJohn Marino 		       struct cmd_list_element *c,
410c50c785cSJohn Marino 		       const char *value)
4115796c8dcSSimon Schubert {
412c50c785cSJohn Marino   fprintf_filtered (file,
413c50c785cSJohn Marino 		    _("The current BFD target is \"%s\".\n"), value);
4145796c8dcSSimon Schubert }
4155796c8dcSSimon Schubert 
416c50c785cSJohn Marino static void set_gnutarget_command (char *, int,
417c50c785cSJohn Marino 				   struct cmd_list_element *);
4185796c8dcSSimon Schubert 
4195796c8dcSSimon Schubert static void
set_gnutarget_command(char * ignore,int from_tty,struct cmd_list_element * c)420c50c785cSJohn Marino set_gnutarget_command (char *ignore, int from_tty,
421c50c785cSJohn Marino 		       struct cmd_list_element *c)
4225796c8dcSSimon Schubert {
423*ef5ccd6cSJohn Marino   char *gend = gnutarget_string + strlen (gnutarget_string);
424*ef5ccd6cSJohn Marino 
425*ef5ccd6cSJohn Marino   gend = remove_trailing_whitespace (gnutarget_string, gend);
426*ef5ccd6cSJohn Marino   *gend = '\0';
427*ef5ccd6cSJohn Marino 
4285796c8dcSSimon Schubert   if (strcmp (gnutarget_string, "auto") == 0)
4295796c8dcSSimon Schubert     gnutarget = NULL;
4305796c8dcSSimon Schubert   else
4315796c8dcSSimon Schubert     gnutarget = gnutarget_string;
4325796c8dcSSimon Schubert }
4335796c8dcSSimon Schubert 
434*ef5ccd6cSJohn Marino /* A completion function for "set gnutarget".  */
435*ef5ccd6cSJohn Marino 
VEC(char_ptr)436*ef5ccd6cSJohn Marino static VEC (char_ptr) *
437*ef5ccd6cSJohn Marino complete_set_gnutarget (struct cmd_list_element *cmd, char *text, char *word)
438*ef5ccd6cSJohn Marino {
439*ef5ccd6cSJohn Marino   static const char **bfd_targets;
440*ef5ccd6cSJohn Marino 
441*ef5ccd6cSJohn Marino   if (bfd_targets == NULL)
442*ef5ccd6cSJohn Marino     {
443*ef5ccd6cSJohn Marino       int last;
444*ef5ccd6cSJohn Marino 
445*ef5ccd6cSJohn Marino       bfd_targets = bfd_target_list ();
446*ef5ccd6cSJohn Marino       for (last = 0; bfd_targets[last] != NULL; ++last)
447*ef5ccd6cSJohn Marino 	;
448*ef5ccd6cSJohn Marino 
449*ef5ccd6cSJohn Marino       bfd_targets = xrealloc (bfd_targets, (last + 2) * sizeof (const char **));
450*ef5ccd6cSJohn Marino       bfd_targets[last] = "auto";
451*ef5ccd6cSJohn Marino       bfd_targets[last + 1] = NULL;
452*ef5ccd6cSJohn Marino     }
453*ef5ccd6cSJohn Marino 
454*ef5ccd6cSJohn Marino   return complete_on_enum (bfd_targets, text, word);
455*ef5ccd6cSJohn Marino }
456*ef5ccd6cSJohn Marino 
4575796c8dcSSimon Schubert /* Set the gnutarget.  */
4585796c8dcSSimon Schubert void
set_gnutarget(char * newtarget)4595796c8dcSSimon Schubert set_gnutarget (char *newtarget)
4605796c8dcSSimon Schubert {
4615796c8dcSSimon Schubert   if (gnutarget_string != NULL)
4625796c8dcSSimon Schubert     xfree (gnutarget_string);
4635796c8dcSSimon Schubert   gnutarget_string = xstrdup (newtarget);
4645796c8dcSSimon Schubert   set_gnutarget_command (NULL, 0, NULL);
4655796c8dcSSimon Schubert }
4665796c8dcSSimon Schubert 
4675796c8dcSSimon Schubert void
_initialize_core(void)4685796c8dcSSimon Schubert _initialize_core (void)
4695796c8dcSSimon Schubert {
4705796c8dcSSimon Schubert   struct cmd_list_element *c;
471cf7f2e2dSJohn Marino 
4725796c8dcSSimon Schubert   c = add_cmd ("core-file", class_files, core_file_command, _("\
4735796c8dcSSimon Schubert Use FILE as core dump for examining memory and registers.\n\
4745796c8dcSSimon Schubert No arg means have no core file.  This command has been superseded by the\n\
4755796c8dcSSimon Schubert `target core' and `detach' commands."), &cmdlist);
4765796c8dcSSimon Schubert   set_cmd_completer (c, filename_completer);
4775796c8dcSSimon Schubert 
4785796c8dcSSimon Schubert 
479*ef5ccd6cSJohn Marino   c = add_setshow_string_noescape_cmd ("gnutarget", class_files,
4805796c8dcSSimon Schubert 				       &gnutarget_string, _("\
4815796c8dcSSimon Schubert Set the current BFD target."), _("\
4825796c8dcSSimon Schubert Show the current BFD target."), _("\
4835796c8dcSSimon Schubert Use `set gnutarget auto' to specify automatic detection."),
4845796c8dcSSimon Schubert 				       set_gnutarget_command,
4855796c8dcSSimon Schubert 				       show_gnutarget_string,
4865796c8dcSSimon Schubert 				       &setlist, &showlist);
487*ef5ccd6cSJohn Marino   set_cmd_completer (c, complete_set_gnutarget);
488*ef5ccd6cSJohn Marino 
489*ef5ccd6cSJohn Marino   add_alias_cmd ("g", "gnutarget", class_files, 1, &setlist);
4905796c8dcSSimon Schubert 
4915796c8dcSSimon Schubert   if (getenv ("GNUTARGET"))
4925796c8dcSSimon Schubert     set_gnutarget (getenv ("GNUTARGET"));
4935796c8dcSSimon Schubert   else
4945796c8dcSSimon Schubert     set_gnutarget ("auto");
4955796c8dcSSimon Schubert }
496