119370Spst/* Core dump and executable file functions below target vector, for GDB. 219370Spst 3130803Smarcel Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 4130803Smarcel 1997, 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation, 5130803Smarcel Inc. 6130803Smarcel 798944Sobrien This file is part of GDB. 819370Spst 998944Sobrien This program is free software; you can redistribute it and/or modify 1098944Sobrien it under the terms of the GNU General Public License as published by 1198944Sobrien the Free Software Foundation; either version 2 of the License, or 1298944Sobrien (at your option) any later version. 1319370Spst 1498944Sobrien This program is distributed in the hope that it will be useful, 1598944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1698944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1798944Sobrien GNU General Public License for more details. 1819370Spst 1998944Sobrien You should have received a copy of the GNU General Public License 2098944Sobrien along with this program; if not, write to the Free Software 2198944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2298944Sobrien Boston, MA 02111-1307, USA. */ 2319370Spst 2419370Spst#include "defs.h" 25130803Smarcel#include "arch-utils.h" 2619370Spst#include "gdb_string.h" 2719370Spst#include <errno.h> 2819370Spst#include <signal.h> 2919370Spst#include <fcntl.h> 3098944Sobrien#ifdef HAVE_SYS_FILE_H 3198944Sobrien#include <sys/file.h> /* needed for F_OK and friends */ 3298944Sobrien#endif 3398944Sobrien#include "frame.h" /* required by inferior.h */ 3419370Spst#include "inferior.h" 3519370Spst#include "symtab.h" 3619370Spst#include "command.h" 3719370Spst#include "bfd.h" 3819370Spst#include "target.h" 3919370Spst#include "gdbcore.h" 4046283Sdfr#include "gdbthread.h" 4198944Sobrien#include "regcache.h" 42130803Smarcel#include "regset.h" 4398944Sobrien#include "symfile.h" 44130803Smarcel#include "exec.h" 45130803Smarcel#include "readline/readline.h" 4619370Spst 47130803Smarcel#include "gdb_assert.h" 48130803Smarcel 4998944Sobrien#ifndef O_BINARY 5098944Sobrien#define O_BINARY 0 5198944Sobrien#endif 5298944Sobrien 5319370Spst/* List of all available core_fns. On gdb startup, each core file register 5419370Spst reader calls add_core_fns() to register information on each core format it 5519370Spst is prepared to read. */ 5619370Spst 5719370Spststatic struct core_fns *core_file_fns = NULL; 5819370Spst 5998944Sobrien/* The core_fns for a core file handler that is prepared to read the core 6098944Sobrien file currently open on core_bfd. */ 6119370Spst 6298944Sobrienstatic struct core_fns *core_vec = NULL; 6398944Sobrien 64130803Smarcel/* FIXME: kettenis/20031023: Eventually this variable should 65130803Smarcel disappear. */ 66130803Smarcel 67130803Smarcelstruct gdbarch *core_gdbarch = NULL; 68130803Smarcel 6998944Sobrienstatic void core_files_info (struct target_ops *); 7098944Sobrien 7119370Spst#ifdef SOLIB_ADD 72130803Smarcelstatic int solib_add_stub (void *); 7319370Spst#endif 7419370Spst 7598944Sobrienstatic struct core_fns *sniff_core_bfd (bfd *); 7619370Spst 77130803Smarcelstatic int gdb_check_format (bfd *); 7819370Spst 7998944Sobrienstatic void core_open (char *, int); 8019370Spst 8198944Sobrienstatic void core_detach (char *, int); 8219370Spst 8398944Sobrienstatic void core_close (int); 8446283Sdfr 8598944Sobrienstatic void core_close_cleanup (void *ignore); 8646283Sdfr 8798944Sobrienstatic void get_core_registers (int); 8846283Sdfr 89130803Smarcelstatic void add_to_thread_list (bfd *, asection *, void *); 9046283Sdfr 9198944Sobrienstatic int ignore (CORE_ADDR, char *); 9246283Sdfr 9398944Sobrienstatic int core_file_thread_alive (ptid_t tid); 9446283Sdfr 9598944Sobrienstatic void init_core_ops (void); 9698944Sobrien 9798944Sobrienvoid _initialize_corelow (void); 9898944Sobrien 9946283Sdfrstruct target_ops core_ops; 10046283Sdfr 10119370Spst/* Link a new core_fns into the global core_file_fns list. Called on gdb 10219370Spst startup by the _initialize routine in each core file register reader, to 10319370Spst register information about each format the the reader is prepared to 10419370Spst handle. */ 10519370Spst 10619370Spstvoid 10798944Sobrienadd_core_fns (struct core_fns *cf) 10819370Spst{ 10998944Sobrien cf->next = core_file_fns; 11019370Spst core_file_fns = cf; 11119370Spst} 11219370Spst 11398944Sobrien/* The default function that core file handlers can use to examine a 11498944Sobrien core file BFD and decide whether or not to accept the job of 11598944Sobrien reading the core file. */ 11619370Spst 11798944Sobrienint 11898944Sobriendefault_core_sniffer (struct core_fns *our_fns, bfd *abfd) 11998944Sobrien{ 12098944Sobrien int result; 12198944Sobrien 12298944Sobrien result = (bfd_get_flavour (abfd) == our_fns -> core_flavour); 12398944Sobrien return (result); 12498944Sobrien} 12598944Sobrien 12698944Sobrien/* Walk through the list of core functions to find a set that can 12798944Sobrien handle the core file open on ABFD. Default to the first one in the 12898944Sobrien list if nothing matches. Returns pointer to set that is 12998944Sobrien selected. */ 13098944Sobrien 13198944Sobrienstatic struct core_fns * 13298944Sobriensniff_core_bfd (bfd *abfd) 13398944Sobrien{ 13498944Sobrien struct core_fns *cf; 13598944Sobrien struct core_fns *yummy = NULL; 13698944Sobrien int matches = 0;; 13798944Sobrien 138130803Smarcel /* Don't sniff if we have support for register sets in CORE_GDBARCH. */ 139130803Smarcel if (core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch)) 140130803Smarcel return NULL; 141130803Smarcel 14298944Sobrien for (cf = core_file_fns; cf != NULL; cf = cf->next) 14398944Sobrien { 14498944Sobrien if (cf->core_sniffer (cf, abfd)) 14598944Sobrien { 14698944Sobrien yummy = cf; 14798944Sobrien matches++; 14898944Sobrien } 14998944Sobrien } 15098944Sobrien if (matches > 1) 15198944Sobrien { 15298944Sobrien warning ("\"%s\": ambiguous core format, %d handlers match", 15398944Sobrien bfd_get_filename (abfd), matches); 15498944Sobrien } 15598944Sobrien else if (matches == 0) 15698944Sobrien { 15798944Sobrien warning ("\"%s\": no core file handler recognizes format, using default", 15898944Sobrien bfd_get_filename (abfd)); 15998944Sobrien } 16098944Sobrien if (yummy == NULL) 16198944Sobrien { 16298944Sobrien yummy = core_file_fns; 16398944Sobrien } 16498944Sobrien return (yummy); 16598944Sobrien} 16698944Sobrien 16798944Sobrien/* The default is to reject every core file format we see. Either 16898944Sobrien BFD has to recognize it, or we have to provide a function in the 16998944Sobrien core file handler that recognizes it. */ 17098944Sobrien 17198944Sobrienint 17298944Sobriendefault_check_format (bfd *abfd) 17398944Sobrien{ 17498944Sobrien return (0); 17598944Sobrien} 17698944Sobrien 17798944Sobrien/* Attempt to recognize core file formats that BFD rejects. */ 17898944Sobrien 179130803Smarcelstatic int 18098944Sobriengdb_check_format (bfd *abfd) 18198944Sobrien{ 18298944Sobrien struct core_fns *cf; 18398944Sobrien 18498944Sobrien for (cf = core_file_fns; cf != NULL; cf = cf->next) 18598944Sobrien { 18698944Sobrien if (cf->check_format (abfd)) 18798944Sobrien { 18898944Sobrien return (1); 18998944Sobrien } 19098944Sobrien } 19198944Sobrien return (0); 19298944Sobrien} 19398944Sobrien 19419370Spst/* Discard all vestiges of any previous core file and mark data and stack 19519370Spst spaces as empty. */ 19619370Spst 19719370Spststatic void 19898944Sobriencore_close (int quitting) 19919370Spst{ 20019370Spst char *name; 20119370Spst 20219370Spst if (core_bfd) 20319370Spst { 20498944Sobrien inferior_ptid = null_ptid; /* Avoid confusion from thread stuff */ 20546283Sdfr 20698944Sobrien /* Clear out solib state while the bfd is still open. See 20798944Sobrien comments in clear_solib in solib.c. */ 20898944Sobrien#ifdef CLEAR_SOLIB 20998944Sobrien CLEAR_SOLIB (); 21098944Sobrien#endif 21198944Sobrien 21219370Spst name = bfd_get_filename (core_bfd); 21319370Spst if (!bfd_close (core_bfd)) 21419370Spst warning ("cannot close \"%s\": %s", 21519370Spst name, bfd_errmsg (bfd_get_error ())); 21698944Sobrien xfree (name); 21719370Spst core_bfd = NULL; 21819370Spst if (core_ops.to_sections) 21919370Spst { 22098944Sobrien xfree (core_ops.to_sections); 22119370Spst core_ops.to_sections = NULL; 22219370Spst core_ops.to_sections_end = NULL; 22319370Spst } 22419370Spst } 22598944Sobrien core_vec = NULL; 226130803Smarcel core_gdbarch = NULL; 22719370Spst} 22819370Spst 22998944Sobrienstatic void 23098944Sobriencore_close_cleanup (void *ignore) 23198944Sobrien{ 23298944Sobrien core_close (0/*ignored*/); 23398944Sobrien} 23498944Sobrien 23519370Spst#ifdef SOLIB_ADD 23619370Spst/* Stub function for catch_errors around shared library hacking. FROM_TTYP 23719370Spst is really an int * which points to from_tty. */ 23819370Spst 23998944Sobrienstatic int 240130803Smarcelsolib_add_stub (void *from_ttyp) 24119370Spst{ 24298944Sobrien SOLIB_ADD (NULL, *(int *) from_ttyp, ¤t_target, auto_solib_add); 24319370Spst re_enable_breakpoints_in_shlibs (); 24419370Spst return 0; 24519370Spst} 24619370Spst#endif /* SOLIB_ADD */ 24719370Spst 24819370Spst/* Look for sections whose names start with `.reg/' so that we can extract the 24919370Spst list of threads in a core file. */ 25019370Spst 25119370Spststatic void 252130803Smarceladd_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg) 25319370Spst{ 25419370Spst int thread_id; 25519370Spst asection *reg_sect = (asection *) reg_sect_arg; 25619370Spst 25719370Spst if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0) 25819370Spst return; 25919370Spst 26019370Spst thread_id = atoi (bfd_section_name (abfd, asect) + 5); 26119370Spst 26298944Sobrien add_thread (pid_to_ptid (thread_id)); 26319370Spst 26419370Spst/* Warning, Will Robinson, looking at BFD private data! */ 26519370Spst 26646283Sdfr if (reg_sect != NULL 26798944Sobrien && asect->filepos == reg_sect->filepos) /* Did we find .reg? */ 26898944Sobrien inferior_ptid = pid_to_ptid (thread_id); /* Yes, make it current */ 26919370Spst} 27019370Spst 27119370Spst/* This routine opens and sets up the core file bfd. */ 27219370Spst 27319370Spststatic void 27498944Sobriencore_open (char *filename, int from_tty) 27519370Spst{ 27619370Spst const char *p; 27719370Spst int siggy; 27819370Spst struct cleanup *old_chain; 27919370Spst char *temp; 28019370Spst bfd *temp_bfd; 28119370Spst int ontop; 28219370Spst int scratch_chan; 28319370Spst 28419370Spst target_preopen (from_tty); 28519370Spst if (!filename) 28619370Spst { 28798944Sobrien error (core_bfd ? 28898944Sobrien "No core file specified. (Use `detach' to stop debugging a core file.)" 28998944Sobrien : "No core file specified."); 29019370Spst } 29119370Spst 29219370Spst filename = tilde_expand (filename); 29319370Spst if (filename[0] != '/') 29419370Spst { 29519370Spst temp = concat (current_directory, "/", filename, NULL); 29698944Sobrien xfree (filename); 29719370Spst filename = temp; 29819370Spst } 29919370Spst 30098944Sobrien old_chain = make_cleanup (xfree, filename); 30119370Spst 30298944Sobrien scratch_chan = open (filename, O_BINARY | ( write_files ? O_RDWR : O_RDONLY ), 0); 30319370Spst if (scratch_chan < 0) 30419370Spst perror_with_name (filename); 30519370Spst 30619370Spst temp_bfd = bfd_fdopenr (filename, gnutarget, scratch_chan); 30719370Spst if (temp_bfd == NULL) 30819370Spst perror_with_name (filename); 30919370Spst 31098944Sobrien if (!bfd_check_format (temp_bfd, bfd_core) && 31198944Sobrien !gdb_check_format (temp_bfd)) 31219370Spst { 31319370Spst /* Do it after the err msg */ 31419370Spst /* FIXME: should be checking for errors from bfd_close (for one thing, 31598944Sobrien on error it does not free all the storage associated with the 31698944Sobrien bfd). */ 31798944Sobrien make_cleanup_bfd_close (temp_bfd); 31819370Spst error ("\"%s\" is not a core dump: %s", 31919370Spst filename, bfd_errmsg (bfd_get_error ())); 32019370Spst } 32119370Spst 32219370Spst /* Looks semi-reasonable. Toss the old core file and work on the new. */ 32319370Spst 32498944Sobrien discard_cleanups (old_chain); /* Don't free filename any more */ 32519370Spst unpush_target (&core_ops); 32619370Spst core_bfd = temp_bfd; 32798944Sobrien old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/); 32819370Spst 329130803Smarcel /* FIXME: kettenis/20031023: This is very dangerous. The 330130803Smarcel CORE_GDBARCH that results from this call may very well be 331130803Smarcel different from CURRENT_GDBARCH. However, its methods may only 332130803Smarcel work if it is selected as the current architecture, because they 333130803Smarcel rely on swapped data (see gdbarch.c). We should get rid of that 334130803Smarcel swapped data. */ 335130803Smarcel core_gdbarch = gdbarch_from_bfd (core_bfd); 336130803Smarcel 33798944Sobrien /* Find a suitable core file handler to munch on core_bfd */ 33898944Sobrien core_vec = sniff_core_bfd (core_bfd); 33998944Sobrien 34019370Spst validate_files (); 34119370Spst 34219370Spst /* Find the data section */ 34319370Spst if (build_section_table (core_bfd, &core_ops.to_sections, 34419370Spst &core_ops.to_sections_end)) 34519370Spst error ("\"%s\": Can't find sections: %s", 34619370Spst bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ())); 34719370Spst 348130803Smarcel /* If we have no exec file, try to set the architecture from the 349130803Smarcel core file. We don't do this unconditionally since an exec file 350130803Smarcel typically contains more information that helps us determine the 351130803Smarcel architecture than a core file. */ 352130803Smarcel if (!exec_bfd) 353130803Smarcel set_gdbarch_from_file (core_bfd); 35498944Sobrien 35519370Spst ontop = !push_target (&core_ops); 35619370Spst discard_cleanups (old_chain); 35719370Spst 35819370Spst p = bfd_core_file_failing_command (core_bfd); 35919370Spst if (p) 36019370Spst printf_filtered ("Core was generated by `%s'.\n", p); 36119370Spst 36219370Spst siggy = bfd_core_file_failing_signal (core_bfd); 36319370Spst if (siggy > 0) 36498944Sobrien /* NOTE: target_signal_from_host() converts a target signal value 36598944Sobrien into gdb's internal signal value. Unfortunately gdb's internal 36698944Sobrien value is called ``target_signal'' and this function got the 36798944Sobrien name ..._from_host(). */ 36819370Spst printf_filtered ("Program terminated with signal %d, %s.\n", siggy, 36998944Sobrien target_signal_to_string (target_signal_from_host (siggy))); 37019370Spst 37119370Spst /* Build up thread list from BFD sections. */ 37219370Spst 37319370Spst init_thread_list (); 37419370Spst bfd_map_over_sections (core_bfd, add_to_thread_list, 37519370Spst bfd_get_section_by_name (core_bfd, ".reg")); 37619370Spst 37719370Spst if (ontop) 37819370Spst { 37919370Spst /* Fetch all registers from core file. */ 38019370Spst target_fetch_registers (-1); 38119370Spst 38219370Spst /* Add symbols and section mappings for any shared libraries. */ 38319370Spst#ifdef SOLIB_ADD 38498944Sobrien catch_errors (solib_add_stub, &from_tty, (char *) 0, 38519370Spst RETURN_MASK_ALL); 38619370Spst#endif 38719370Spst 38819370Spst /* Now, set up the frame cache, and print the top of stack. */ 38919370Spst flush_cached_frames (); 390130803Smarcel select_frame (get_current_frame ()); 391130803Smarcel print_stack_frame (deprecated_selected_frame, 392130803Smarcel frame_relative_level (deprecated_selected_frame), 1); 39319370Spst } 39419370Spst else 39519370Spst { 39619370Spst warning ( 39798944Sobrien "you won't be able to access this core file until you terminate\n\ 39819370Spstyour %s; do ``info files''", target_longname); 39919370Spst } 40019370Spst} 40119370Spst 40219370Spststatic void 40398944Sobriencore_detach (char *args, int from_tty) 40419370Spst{ 40519370Spst if (args) 40619370Spst error ("Too many arguments"); 40719370Spst unpush_target (&core_ops); 40819370Spst reinit_frame_cache (); 40919370Spst if (from_tty) 41019370Spst printf_filtered ("No core file now.\n"); 41119370Spst} 41219370Spst 41319370Spst 41498944Sobrien/* Try to retrieve registers from a section in core_bfd, and supply 41598944Sobrien them to core_vec->core_read_registers, as the register set numbered 41698944Sobrien WHICH. 41719370Spst 41898944Sobrien If inferior_ptid is zero, do the single-threaded thing: look for a 41998944Sobrien section named NAME. If inferior_ptid is non-zero, do the 42098944Sobrien multi-threaded thing: look for a section named "NAME/PID", where 42198944Sobrien PID is the shortest ASCII decimal representation of inferior_ptid. 42219370Spst 42398944Sobrien HUMAN_NAME is a human-readable name for the kind of registers the 42498944Sobrien NAME section contains, for use in error messages. 42519370Spst 42698944Sobrien If REQUIRED is non-zero, print an error if the core file doesn't 42798944Sobrien have a section by the appropriate name. Otherwise, just do nothing. */ 42819370Spst 42998944Sobrienstatic void 43098944Sobrienget_core_register_section (char *name, 43198944Sobrien int which, 43298944Sobrien char *human_name, 43398944Sobrien int required) 43498944Sobrien{ 435277816Spfg static char *section_name = NULL; 436130803Smarcel struct bfd_section *section; 43798944Sobrien bfd_size_type size; 43898944Sobrien char *contents; 43919370Spst 440277816Spfg xfree (section_name); 44198944Sobrien if (PIDGET (inferior_ptid)) 442277816Spfg section_name = xstrprintf ("%s/%d", name, PIDGET (inferior_ptid)); 44319370Spst else 444277816Spfg section_name = xstrdup (name); 44519370Spst 44698944Sobrien section = bfd_get_section_by_name (core_bfd, section_name); 44798944Sobrien if (! section) 44819370Spst { 44998944Sobrien if (required) 45098944Sobrien warning ("Couldn't find %s registers in core file.\n", human_name); 45198944Sobrien return; 45219370Spst } 45398944Sobrien 45498944Sobrien size = bfd_section_size (core_bfd, section); 45598944Sobrien contents = alloca (size); 45698944Sobrien if (! bfd_get_section_contents (core_bfd, section, contents, 45798944Sobrien (file_ptr) 0, size)) 45819370Spst { 45998944Sobrien warning ("Couldn't read %s registers from `%s' section in core file.\n", 46098944Sobrien human_name, name); 46198944Sobrien return; 46219370Spst } 46319370Spst 464130803Smarcel if (core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch)) 465130803Smarcel { 466130803Smarcel const struct regset *regset; 467130803Smarcel 468130803Smarcel regset = gdbarch_regset_from_core_section (core_gdbarch, name, size); 469130803Smarcel if (regset == NULL) 470130803Smarcel { 471130803Smarcel if (required) 472130803Smarcel warning ("Couldn't recognize %s registers in core file.\n", 473130803Smarcel human_name); 474130803Smarcel return; 475130803Smarcel } 476130803Smarcel 477130803Smarcel regset->supply_regset (regset, current_regcache, -1, contents, size); 478130803Smarcel return; 479130803Smarcel } 480130803Smarcel 481130803Smarcel gdb_assert (core_vec); 482130803Smarcel core_vec->core_read_registers (contents, size, which, 48398944Sobrien ((CORE_ADDR) 48498944Sobrien bfd_section_vma (core_bfd, section))); 48519370Spst} 48619370Spst 48746283Sdfr 48898944Sobrien/* Get the registers out of a core file. This is the machine- 48998944Sobrien independent part. Fetch_core_registers is the machine-dependent 49098944Sobrien part, typically implemented in the xm-file for each architecture. */ 49146283Sdfr 49298944Sobrien/* We just get all the registers, so we don't use regno. */ 49346283Sdfr 49498944Sobrienstatic void 49598944Sobrienget_core_registers (int regno) 49698944Sobrien{ 49798944Sobrien int status; 49846283Sdfr 499130803Smarcel if (!(core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch)) 500130803Smarcel && (core_vec == NULL || core_vec->core_read_registers == NULL)) 50146283Sdfr { 50298944Sobrien fprintf_filtered (gdb_stderr, 50398944Sobrien "Can't fetch registers from this type of core file\n"); 50498944Sobrien return; 50546283Sdfr } 50646283Sdfr 50798944Sobrien get_core_register_section (".reg", 0, "general-purpose", 1); 50898944Sobrien get_core_register_section (".reg2", 2, "floating-point", 0); 50998944Sobrien get_core_register_section (".reg-xfp", 3, "extended floating-point", 0); 51046283Sdfr 511130803Smarcel deprecated_registers_fetched (); 51246283Sdfr} 51346283Sdfr 51419370Spststatic void 51598944Sobriencore_files_info (struct target_ops *t) 51619370Spst{ 51719370Spst print_section_info (t, core_bfd); 51819370Spst} 51919370Spst 520130803Smarcelstatic LONGEST 521130803Smarcelcore_xfer_partial (struct target_ops *ops, enum target_object object, 522130803Smarcel const char *annex, void *readbuf, 523130803Smarcel const void *writebuf, ULONGEST offset, LONGEST len) 524130803Smarcel{ 525130803Smarcel switch (object) 526130803Smarcel { 527130803Smarcel case TARGET_OBJECT_MEMORY: 528130803Smarcel if (readbuf) 529132685Smarcel return (*ops->to_xfer_memory) (offset, readbuf, len, 0/*read*/, 530130803Smarcel NULL, ops); 531130803Smarcel if (writebuf) 532132685Smarcel return (*ops->to_xfer_memory) (offset, writebuf, len, 1/*write*/, 533130803Smarcel NULL, ops); 534130803Smarcel return -1; 535130803Smarcel 536130803Smarcel case TARGET_OBJECT_AUXV: 537130803Smarcel if (readbuf) 538130803Smarcel { 539130803Smarcel /* When the aux vector is stored in core file, BFD 540130803Smarcel represents this with a fake section called ".auxv". */ 541130803Smarcel 542130803Smarcel struct bfd_section *section; 543130803Smarcel bfd_size_type size; 544130803Smarcel char *contents; 545130803Smarcel 546130803Smarcel section = bfd_get_section_by_name (core_bfd, ".auxv"); 547130803Smarcel if (section == NULL) 548130803Smarcel return -1; 549130803Smarcel 550130803Smarcel size = bfd_section_size (core_bfd, section); 551130803Smarcel if (offset >= size) 552130803Smarcel return 0; 553130803Smarcel size -= offset; 554130803Smarcel if (size > len) 555130803Smarcel size = len; 556130803Smarcel if (size > 0 && 557130803Smarcel ! bfd_get_section_contents (core_bfd, section, readbuf, 558130803Smarcel (file_ptr) offset, size)) 559130803Smarcel { 560130803Smarcel warning ("Couldn't read NT_AUXV note in core file."); 561130803Smarcel return -1; 562130803Smarcel } 563130803Smarcel 564130803Smarcel return size; 565130803Smarcel } 566130803Smarcel return -1; 567130803Smarcel 568132685Smarcel case TARGET_OBJECT_DIRTY: 569132685Smarcel { 570132685Smarcel ULONGEST addr; 571132685Smarcel addr = *(ULONGEST*)annex + offset; 572132685Smarcel if (readbuf) 573132685Smarcel return (*ops->to_xfer_memory) (addr, readbuf, len, 0/*read*/, 574132685Smarcel NULL, ops); 575132685Smarcel if (writebuf) 576132685Smarcel return (*ops->to_xfer_memory) (addr, writebuf, len, 1/*write*/, 577132685Smarcel NULL, ops); 578132685Smarcel return -1; 579132685Smarcel } 580132685Smarcel 581130803Smarcel default: 582130803Smarcel if (ops->beneath != NULL) 583130803Smarcel return ops->beneath->to_xfer_partial (ops->beneath, object, annex, 584130803Smarcel readbuf, writebuf, offset, len); 585130803Smarcel return -1; 586130803Smarcel } 587130803Smarcel} 588130803Smarcel 589130803Smarcel 59019370Spst/* If mourn is being called in all the right places, this could be say 59119370Spst `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */ 59219370Spst 59319370Spststatic int 59498944Sobrienignore (CORE_ADDR addr, char *contents) 59519370Spst{ 59619370Spst return 0; 59719370Spst} 59819370Spst 59919370Spst 60046283Sdfr/* Okay, let's be honest: threads gleaned from a core file aren't 60146283Sdfr exactly lively, are they? On the other hand, if we don't claim 60246283Sdfr that each & every one is alive, then we don't get any of them 60346283Sdfr to appear in an "info thread" command, which is quite a useful 60446283Sdfr behaviour. 60598944Sobrien */ 60646283Sdfrstatic int 60798944Sobriencore_file_thread_alive (ptid_t tid) 60846283Sdfr{ 60946283Sdfr return 1; 61046283Sdfr} 61146283Sdfr 61246283Sdfr/* Fill in core_ops with its defined operations and properties. */ 61346283Sdfr 61446283Sdfrstatic void 61598944Sobrieninit_core_ops (void) 61646283Sdfr{ 61746283Sdfr core_ops.to_shortname = "core"; 61846283Sdfr core_ops.to_longname = "Local core dump file"; 61946283Sdfr core_ops.to_doc = 62046283Sdfr "Use a core file as a target. Specify the filename of the core file."; 62146283Sdfr core_ops.to_open = core_open; 62246283Sdfr core_ops.to_close = core_close; 62346283Sdfr core_ops.to_attach = find_default_attach; 62446283Sdfr core_ops.to_detach = core_detach; 62546283Sdfr core_ops.to_fetch_registers = get_core_registers; 626130803Smarcel core_ops.to_xfer_partial = core_xfer_partial; 62746283Sdfr core_ops.to_xfer_memory = xfer_memory; 62846283Sdfr core_ops.to_files_info = core_files_info; 62946283Sdfr core_ops.to_insert_breakpoint = ignore; 63046283Sdfr core_ops.to_remove_breakpoint = ignore; 63146283Sdfr core_ops.to_create_inferior = find_default_create_inferior; 63246283Sdfr core_ops.to_thread_alive = core_file_thread_alive; 63346283Sdfr core_ops.to_stratum = core_stratum; 63446283Sdfr core_ops.to_has_memory = 1; 63546283Sdfr core_ops.to_has_stack = 1; 63646283Sdfr core_ops.to_has_registers = 1; 63798944Sobrien core_ops.to_magic = OPS_MAGIC; 63846283Sdfr} 63946283Sdfr 64046283Sdfr/* non-zero if we should not do the add_target call in 64146283Sdfr _initialize_corelow; not initialized (i.e., bss) so that 64246283Sdfr the target can initialize it (i.e., data) if appropriate. 64346283Sdfr This needs to be set at compile time because we don't know 64446283Sdfr for sure whether the target's initialize routine is called 64546283Sdfr before us or after us. */ 64646283Sdfrint coreops_suppress_target; 64746283Sdfr 64819370Spstvoid 64998944Sobrien_initialize_corelow (void) 65019370Spst{ 65146283Sdfr init_core_ops (); 65246283Sdfr 65346283Sdfr if (!coreops_suppress_target) 65446283Sdfr add_target (&core_ops); 65519370Spst} 656